FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
Recuerdo haber probado alguna vez también de pasar punteros como parámetros en funciones de DLLs y tener los mismos problemas que tu dices, por lo que creo que el código de la DLL y el de el EXE no se cargan en el mismo espacio de memoria. Yo he usado el File Mapping para compartir records entre dos EXEs pero creo que funcionaria igual entre un EXE y una DLL. Haz una prueba, no es muy complicado de usar y tampoco se me ocurre otro sistema.
|
#2
|
|||
|
|||
Problemas con parametros
Hola muy buenas cht666cht, me he decidido a provar lo de File Mapping, y me encuentro con problemas debido a mi desconocimiento de estos metodos. A ver
Yo desde Delphi , cargaba la libreria del modo Handler := LoadLibrary(Pchar('Parser.dll')) y luego para llamar a los metodos de la dll ,por ejemplo @IniciaGL := GetProcAddress(Handler,PChar('IniciarGL')); if @IniciaGL <>nil then IniciaGL(FTop.Handle,C_TOP); donde IniciaGl es una variable del tipo procedure con la misma estructura que tenga la función en la dll. Hasta aqui es como yo vengo utilizando la dll, i en esta manera de funcionar en donde tengo problemas a la hora de pasar records. He estado mirando el help que me dijiste i deversa documentación en internet i he creado un fileMapping de la siguiente manera Hfitxer := CreateFile(Pchar('Parser.dll'),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,0); Handler := CreateFileMapping(Hfitxer,nil,PAGE_READWRITE,0,0,MAPNAME); Pero hasta aqui bién , pero al hacer un GetprocAddress(Handler,'XXXXX') no encuentra ninguna función, en que he cometido el error? Supongo que el error debe ser de concepto, y te agradezco tu paciencia conmigo ya que este tema para mi es del todo novedoso. Muchas gracias por adelantado!!! |
#3
|
|||
|
|||
Mira, he estado mirando el código que utilicé para compartir un record entre dos aplicaciones. Básicamente seria algo asi:
1. Tanto en el EXE como en la DLL has de declarar el mismo record en el que estará la información que quieres compartir: type TDatos = packed record a, b, c: Integer; end; PDatos = ^TDatos; // el tipo PDatos será un puntero a un TDatos y una variable para acceder al mismo: var Datos: PDatos; 2. El siguiente paso es reservar la memoria, y eso lo ha de hacer o el EXE o la DLL, en una funcíón de inicialización, en el OnCreate o donde lo creas conveniente: FileMappingObject := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, SizeOf(TDatos), 'IDENTIFICADOR_DEL_FILEMAPPING'); Datos := MapViewOfFile(FileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0); Mutex := CreateMutex(nil, False, 'IDENTIFICADOR_DEL_MUTEX'); También se crea un mutex, que es el objeto mediante el cual sincronizaremos el acceso a la memoria. recuerda declarar las variables 'FileMappingObject' y 'Mutex' , de tipo THandle. y para liberar la memoria y el mutex: CloseHandle(Mutex); UnmapViewOfFile(Datos); CloseHandle(FileMappingObject); Esto en la funcion de finalización, en el OnDestroy, etc... 3. En el resto de procesos que vayan a acceder a esa zona de memoria, obtendras el puntero y el identificador del mutex asi: FileMappingObject := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, 'IDENTIFICADOR_DEL_FILEMAPPING'); Datos := MapViewOfFile(FileMappingObject, FILE_MAP_ALL_ACCESS, 0, 0, 0); Mutex := OpenMutex(SYNCHRONIZE, True, 'IDENTIFICADOR_DEL_MUTEX'); o sea, que si el paso 2 lo has hecho en la DLL, en el EXE tendrás que hacer esto. usa el mismo codigo del paso 2 para liberar los objetos. 4. Ahora ya puedes acceder a la estructura 'Datos' tanto desde el EXE como de la DLL. Para eso utiliza este código: // esperar hasta tener acceso if WaitForSingleObject(Mutex, INFINITE) <> WAIT_FAILED then begin // aqui se puede trabajar con 'Datos' ... // al final liberar el mutex para que otro proceso pueda acceder ReleaseMutex(Mutex); end; Esto es todo, espero que te sirva para lo que necesitas. Un saludo. |
#4
|
||||
|
||||
Lamento llegar un poco tarde... pero quiero apuntar que si es posible pasar y recibir estructuras (records) en los parámetros de llamadas a rutinas de una DLL escrita en otro lenguaje. Basta con ver las llamadas al API de windows que se hacen desde Delphi.
Lo que hay que tener en cuenta, es el esquema de paso de parámetros (calling convention) que se utilizará. Si las rutinas están escritas en C/C++ yo te recomiendo usar stdcall (verificando que la dll sea construida respetando esta convención). Cita:
Cita:
Por último... aunque es algo básico, verificar si los parámetros se están pasando por referencia... hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate Última edición por jachguate fecha: 19-02-2004 a las 17:48:15. |
#5
|
|||
|
|||
Problemas con parametros
Hola muy buenas cht666cht he seguido todos tus pasos y funciona con normalidad, una ultima consulta si tengo X diferentes records , he de realizar lo del FileMapping para cada uno de ellos? si,verdad?.
Bueno solo me queda darte de verdad muchas grácias por tu ayuda, y si tienes alguna consulta en la que te pueda ayudar , no dudes en preguntarme. Muchas gracias. |
|
|
|