FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Buscar | Temas de Hoy | Marcar Foros Como Leídos |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Parametros entre Delphi i c++ Builder
Hola muy buenas a todos/as!!!
Necesitaria si alguien tiene como pasar como parametro "records" entre una dll hecha en C++ (structs) y un programa que llama a la dll en delphi . Intento pasarlo utilizando packed records en el lado delphi i structs en la parte de c++, lo he intentado con punteros pero no consigo que a la dll le lleguen los valores correctos ni que la dll retorne valores. Muchas gracias!! |
#2
|
|||
|
|||
Para esto creo que deberías usar File Mapping, que te permite compartir una zona de memoria entre distintos procesos. Mira en la ayuda que viene con Delphi (Win32 Programmer's Reference).
Un saludo. |
#3
|
|||
|
|||
problemas con parametros
Muchas gracias por responder cht666ch.
Pero he estado mirando la ayuda que me dices, y lo del file Mapping es para cuando hay mas de un proceso atacando contra un mismo fichero. Yo el problemas lo tengo con un unico proceso. Estoy creando un editor de vrml, en el que el motor grafico i el parser ,estan en una dll ( que estoy desarrollando en C++ Builder 6.0) , en cambio la interficie del editor la estoy desarrollando en Delphi 5.0 , y desde la interficie se carga la dll y hago llamadas afunciones que exporto de la dll, con todas las funciones com parametros simples no hay problema, pero ahora mew he visto con la necesidad de pasar parametros de tipo Struct o record entre la interficie y la dll, pero ni a la dll le llegan el record con los valores que le paso a la dll , ni la dll devuelve los valores modicados. Yo me temo que no sea alguna opción del project. De todas maneras muchas gracias. Si piensas que me equivoco en algo no dudes en decirmelo. |
#4
|
|||
|
|||
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.
|
#5
|
|||
|
|||
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!!! |
#6
|
|||
|
|||
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. |
#7
|
||||
|
||||
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. |
#8
|
|||
|
|||
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. |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
|