Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Enlazar Librería Dll .NET en Delphi (https://www.clubdelphi.com/foros/showthread.php?t=68379)

vejerf 10-06-2010 10:32:35

Enlazar Librería Dll .NET en Delphi
 
Buenos días a todos,
Tengo el siguiente problema. Estoy desarrollando un proyecto en el que tengo que integrarme con otra aplicación. Para ello tengo una librería dll de la otra aplicación con la que debería de realizar la integración. Yo programo en Delphi con el BDS2006. Según me han dicho la librería de la otra aplicación está desarrollada en .NET.

He referenciado la función de la dll de la siguiente forma:
Código Delphi [-]
function dllfunction(Par1: String; Par2: Double; Par3: Integer; Par4: TXSDateTime): String; stdcall; external 'dlllibrary.dll';

Y después la uso directamente:
Código Delphi [-]
...
dllfunction(myString,myDouble,myInteger,myTXSDateTime);
...

La aplicación compila pero cuando la inicio desde el BDS se me detiene al inicializar y si le doy a continuar da una excepción EAccessViolation.

¿Qué estoy haciendo mal?¿Qué puede estar ocurriendo?

Necesito ayuda, es urgente :(

vejerf 10-06-2010 13:15:34

Hola de nuevo,

He probado simplemente a cargar y liberar la librería y sí he podido, es decir:

Código Delphi [-]
var
  LibHandle : THandle;
begin
  LibHandle := LoadLibrary('dlllibrary.dll');
  Free(LibHandle);
end;

Esto sí funciona. Ahora lo que pretendo es encontrar la función que quiero usar con GetProcAddress pero no entiendo como se hace.

Espero vuestra ayuda. Muchas gracias.

vejerf 10-06-2010 18:03:10

Siguiendo con la investigación y con el tema he dado con lo siguiente que no es más que la carga de la librería dinámicamente
Código Delphi [-]
type
  TDLLFUNC = function(Par1: String; Par2: Double; Par3: Integer; Par4: TXSDateTime): String;
...
procedure PruebaCargaFuncion;
var
  LibHandle: THandle;
  DLLFunc: TDLLFunc;
  Resultado : String;
begin
  LibHandle := LoadLibrary('dlllibrary.dll');  
  try
    @DLLFunc := GetProcAddress(LibHandle,'DllFunction');
    if Assigned(DLLFunc) then
      Resultado := DLLFunc(MyString,MyDouble,MyInteger,MyTXSDateTime);
  finally
    Free(LibHandle);
  end;
end;

Ejecutando en el depurador me dice que 'Not enough actual parameters' cuando miro la variable DLLFunc y por supuesto nunca asigna la función. Ya no sé por donde seguir. Gracias.

Ñuño Martínez 14-06-2010 22:34:46

Cita:

Empezado por vejerf (Mensaje 366878)
Ejecutando en el depurador me dice que 'Not enough actual parameters' cuando miro la variable DLLFunc y por supuesto nunca asigna la función. Ya no sé por donde seguir.

Cuando dices "cuando miro la variable DLLFunc", ¿te refieres a la línea "if Assigned(DLLFunc) then"?

vejerf 15-06-2010 11:09:05

Sí Nuño a eso me refería.

Ejecutando el programa paso a paso voy viendo el valor que toman las variables locales como DLLFunc. En todo el proceso veo que DLLFunc no tiene ningún valor y en el depurador me sale ese mensaje de 'Not enough actual parameters'.

Saludos!

Ñuño Martínez 15-06-2010 12:03:39

No sé si será o no será, pero creo que está intentando llamar a la función y no comprobando el valor del puntero, y de ahí que diga que no tiene suficientes parámetros. Prueba con "if Assigned(@DLLFunc) then", a ver.

Personalmente no me gusta nada cómo maneja Delphi los punteros a función. Prefiero con mucho cómo lo hace Free Pascal, que es mucho más coherente (al estilo "C").

vejerf 15-06-2010 12:51:03

Gracias por contestar Nuño... pero no es por eso.
Como no entendía muy bien que es lo que se estaba haciendo ya había probado esa posible solución, pero sigue ocurriendo lo mismo.

Gracias de todas formas!

vejerf 15-06-2010 18:22:03

Siguiendo con la investigación he visto alguna página donde se dice que no se puede acceder a una clase exportada por una DLL.

Si esto es así por ahí puede venir el fallo ya que la función pertenece a una clase según veo en el código fuente.

¿Alguien me puede aportar datos sobre esto?

Saludos!

Ñuño Martínez 16-06-2010 09:22:16

Amigo, eso cambia las cosas. Evidentemente no puedes exportar un método de una clase si no conoces la definición de la clase. Y aun conociéndola sería difícil, ya que deberías reproducir dicha clase con exactitud. Lo resalto porque esa exactitud ha de ser a nivel de octeto (byte), lo cual es muy difícil conseguir con Delphi.

Para hacerlo es necesario crear una función o procedimiento de molde. Un ejemplo en C++ (compilador desconocido):
Código:

  class TMiClase
  {
  public:
    void Metodo (void) { ; }
  };

  extern "C" TMiClase* CreaObjeto (void) __dlldecl
  {
    return new TMiclase ();
  }

  extern "C" void MoldeAMetodo (TMiClase *Objeto) __dlldecl
  {
    Objeto->Metodo ();
  }

// Etcétera...

Ahora sí, en Delphi:
Código Delphi [-]
UNIT MetodosExportados;

INTERFACE

TYPE
  TMiClase = POINTER;

  FUNCTION CreaObjeto: TMiClase; CDECL; EXTERNAL 'original.dll';
  PROCEDURE MoldeAMetodo (Objeto: TMiClase); CDECL; EXTERNAL 'original.dll';
{ Etcétera... }

IMPLEMENTATION
END.

mcs 16-06-2010 09:47:26

Y no puede ser que desde una aplicación Win32 nativa (como cualquier desarrollada en Delphi) no se pueda acceder a una DLL escrita en .NET, que ni siquiera está compilada a código máquina? Recordar que la citada DLL lo único que debe tener es bytecode CLR...


La franja horaria es GMT +2. Ahora son las 04:12:50.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi