 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Niteman Lt

Registrado: 19 Dic 2002Mensajes: 92Ubicación: Sant Boi (Barcelona)
|
Publicado: Mie 16 May, 2007 4:37 pm Asunto: Cargar varias DLL's y asociar a los COM |
|
|
Voy a intentar explicarme.
En mi trabajo diseñamos y fabricamos equipos que se comunican mediante RS232 con el PC. Cada equipo tiene una DLL propia, pero con la particularidad de que todas las DLL llevan definidas las mismas funciones, solo que internamente (en la DLL) hacen funciones diferentes.
Hasta ahora los procesos de ajuste de los equipos via RS232 se hacian de uno en uno por lo que, de una manera sencilla, hacia un LoadLibrary desde mi programa principal, buscaba las direcciones de las funciones internas y seguidamente ejecutaba la inicialización del puerto COM correspondiente. Ésta inicialización generada por la propia DLL crea un fichero asociando el puerto serie correspondiente con la DLL en cuestion (generando un nCOMId). A partir de aquí, cualquier función que se ejecuta de la DLL pasa por ese puerto serie nCOMId.
El problema viene ahora. Me han encargado la actualización del programa y uno de los requisitos es que pueda cargar varias DLL's, asociar cada DLL a su puerto COM correspondiente y que al ejecutar una funcion de mi programa, y comun para todas las DLL's, se comunique solo con la DLL que se desea.
Alguien sabe como hacerlo?
No se si me he expresado bien.
Actualmente es:
//CPP encargado de cargar la DLL. He obviado parte del código.
hinstDll = LoadLibrary(dllname); //carga de la DLL
(FARPROC) lpfnInitRs232 = GetProcAddress(hinstDll ,"_InitRs232"); //carga de la función interna de la DLL
//en una parte del programa llamo a la funcion
(*lpfnInitRs232) (com.c_str(),ptrDades->p1.c_str() ,ptrDades->p2.c_str() ,ptrDades->p3.c_str() ,ptrDades->p4.c_str());
//Y en la DLL se asocia la DLL con el COM generando el nComId.
nComID = CreateFile(port,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0)) == INVALID_HANDLE_VALUE
Lo que no puedo hacer es que si un PC dispone de 4 puertos serie, tener 4 veces el mismo código solo que cambiando las funciones en el programa. Esto seria larguiiiisimo.
Gracias por anticipado. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Mie 16 May, 2007 7:33 pm Asunto: |
|
|
Pensado en tu problema quiero intentar dibujar lo que tengo en mente,
| Código: | Tu PC Pc "X"
com1 (dll1)\ / com1 (dll1)
com2 (dll2)\\ // com2 (dll2)
<------->
* com3 (dll3)// \\ com3 (dll3) *
com4 (dll4)/ \ com4 (dll4) |
y cuando tu PC le envie datos por el com3, la otra Pc, deba recibirlos en el com3, (aqui no creo que haya problema o si?) pues estan conectados por el mismo cable en el mismo puerto,
si entendí tu problema, si tu pc envia desde el puerto com1 al puerto com4 de la otra pc, quieres que el "otro" programa al recibirlo en el com1, que eso es lo que hace, lo deseche y lo envie al correspondiente com4?, bien lo mas factible y recomendable es que generes una sola Libreria DLL o bien varias como tienes el caso, donde generalices las funciones de la DLL, por que? bien, por que al cargar una Dll en un puerto espesifico, la DLL solo escuchara este puerto y cuando no tenga nada que escuchar la DLL se encuetra en estado de reposo.
dices que envias informacion de tu PC como ejemplo a otras, bien, la cuestion aqui es la capa Fisica de Datos.. que solo llega por un determinado puerto.
Miralo de esta manera, las DLL's son guardias de un salon, entonces existen 4 guardias. tu llevas un pase para entrar con el guardia 3, pero has salido de la puerta 1, al llegar a la puerta de salon, ya que el unico "tunel" es de la puerta1 a la puerta1, quien es el guardia que va a recibirte (en este caso la dll) pues el guardia de la puerta1, tu le dices traigo un encargo para el guardia3, el guardia 1 te va a contestar Aqui no existe. la idea base es que exista un Solo Guardia (una Dll General), que controle los 4 puertos, y ahi entonces puedes delegar la informacion dependiendo a que puerto quieres escuchar)
si no es lo que he entendido, puedes darme mas detalles Técnicos, lo del codigo no es problema, ya que puedes generar una Dll que Active los nPuertos por donde vas a escuchar. y posteriormente en tu cadena de envio... indicas el puerto que quieres que te escuche, no importa si llegas por el 1, 2, 3 o 4
puedes enviar algo como esto
| Código: | Enviar_Mensaje(Puerto, Mensaje) |
Cuando la otra maquina lo reciba... checará primero el puerto a travez de la DLL y delegará la informacion a la funcion requerida... puede ser algo engorroso, pero a los avances que es una actualización y no una creación desde cero, tienes que "parchar" el programa en lugar de redefinir y diseñar una Dll que cumpla tus condiciones.
Saludos. _________________
 |
|
| Volver arriba |
|
 |
Niteman Lt

Registrado: 19 Dic 2002Mensajes: 92Ubicación: Sant Boi (Barcelona)
|
Publicado: Jue 17 May, 2007 7:06 am Asunto: |
|
|
Hola Cesar.
Te has acercado pero no es así. Voy a intentar explicarme mejor.
La empresa fabrica equipos electronicos (varios modelos) que llevan provisto un solo puerto COM. Cada modelo de equipo tiene su propia DLL con la particularidad que el nombre y numero de funciones implementadas en cada DLL son las mismas solo que internamente hacen cosas diferentes. Por ejemplo, la función de inicialización del puerto COM que puse anteriormente esta implementada exactamente igual en todas las DLL's.
El usuario es el que le dice al programa que equipo (modelo de equipo) está conectado a cada puerto COM. Ej. Equipo1 del Modelo1 en COM1, Equipo1 del Modelo2 en COM2 y Equipo2 del Modelo1 en COM3. Obviamente, la combinación de equipos conectados a los diferentes puertos es casi enorme. Además el usuario decide si conectar un solo equipo o varios.
Supongo que el problema está en como generar de manera dinamica tantos hinstDll como equipos tenga conectados, como cargar en memoria la misma funcion pero con diferente hinstDll y como ejecutar una función y que sepa a que DLL dirigirse.
Salu2. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 17 May, 2007 8:11 am Asunto: |
|
|
y no te vendria bien un vector de Dll's, generas cuantas quieras y las vas creando dinamicamente y asignando y borrando cuando ya no te sirvan.
en el foro existe informacion sobre componentes en vectores, quiero pedirte una disculpa por no darte un link, pero me ha costado mucho abrir la pagina del foro, espero que mañana pueda abrirlo y darte los links correspondientes,
Saludos. _________________
 |
|
| Volver arriba |
|
 |
Niteman Lt

Registrado: 19 Dic 2002Mensajes: 92Ubicación: Sant Boi (Barcelona)
|
Publicado: Vie 18 May, 2007 8:03 am Asunto: |
|
|
Hola Cesar. Gracias por tu respuesta, pero vamos a ir por partes, como diria el descuartizador de Boston.
Creo que he entendido tu idea. Supongo que la idea es guardar en un vector las direcciones que devuelve GetProcAddress al cargar las funciónes exportadas de la DLL y luego recoger desde el vector esa dirección en el momento de ejecutar la función. Me equivoco?
En el CPP creo el vector y su puntero.
vector<TDLL> DLL;
vector<TDLL>::iterator ptrDLL;
Y ahora, en el .h deberia definir que es TDLL. He pensado definir TDLL como una estructura dónde cada elemento es una función de la DLL. Pero no se si es lo correcto.
Cesar, tu que opinas?
Salu2. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Vie 18 May, 2007 8:15 am Asunto: |
|
|
| Niteman escribió: | Supongo que la idea es guardar en un vector las direcciones que devuelve GetProcAddress al cargar las funciónes exportadas de la DLL y luego recoger desde el vector esa dirección en el momento de ejecutar la función. Me equivoco?
|
No, efectivamente es correcto.
| Niteman escribió: | En el CPP creo el vector y su puntero.
vector<TDLL> DLL;
vector<TDLL>::iterator ptrDLL;
Y ahora, en el .h deberia definir que es TDLL. He pensado definir TDLL como una estructura dónde cada elemento es una función de la DLL. Pero no se si es lo correcto.
|
Tambien es correcto, aun que aqui quiero hacer mencion a unos pequeños ajustes.
La direccion de GetProcAddres, o en este caso la direccion de hinstDll siempre, es la misma, cuando no es la misma es cuando generas de manera automatica o dinamica, las operaciones como esto
cada vez que generas una "nueva" instancia de una DLL esta se almacena en alguna posicion de la memoria, no siendo asi, que la Dll se carga en una sola direccion, si accedes desde el
vector 1 - offset[50000]
vector 2 - offset[30000]
son diferentes posiciones de Memoria, pero cada una de ellas tiene la direccion de la Misma DLL, esto no cambia en absoluto, en relativa, estas accediendo a la misma DLL, pero desde una posicion diferente de memoria
| Código: | vector<TDLL>::iterator ptrDLL; |
| Cita: | //CPP encargado de cargar la DLL. He obviado parte del código.
hinstDll = LoadLibrary(dllname); //carga de la DLL
(FARPROC) lpfnInitRs232 = GetProcAddress(hinstDll ,"_InitRs232"); //carga de la función interna de la DLL |
Puedes generar un tipo de datos o un Template <T> para crear las instancias de los elementos del Vector
#typedef ((FARPROC) lpfnInitRs232) TDLL
(eso es un ejemplo)
y de ahi generas el vector de Datos para los tipos TDLL
Saludos, espero haberte dado una idea mas clara _________________
 |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|