Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-09-2019
Diego E. Diego E. is offline
Miembro
 
Registrado: mar 2018
Posts: 30
Poder: 0
Diego E. Va por buen camino
Post Uso de dll externa en Delphi

Hola amigos, estoy adentrándome en territorio nuevo y espero puedan ayudarme.

Estoy realizando un proyecto Delphi, para el que necesito usar una dll hecha para C/C++ o Visual Basic 6, en la documentación de la dll no viene la forma de implementar en Delphi(no es sorpresa) ni describe los comandos dentro de ella como para hacer el típico procedimiento de:

Código Delphi [-]
function DoMath(X, Y: Integer): Integer; cdecl; external 'exampleDLL.dll';

Es la primera vez que voy a trabajar con dll's y ciertamente no se usar C++, se que la información va de casi a totalmente nula, pero alguno tiene alguna referencia de como trabajar dicha dll (o en general cualquier dll hecha en un lenguaje externo a Delphi).

Adjunto un poco del código que viene en la documentación de la dll:

Código:
struct SSP_COMMAND { 
SSP_FULL_KEY Key; 
unsigned long BaudRate; 
unsigned long Timeout; 
unsigned char PortNumber; 
unsigned char SSPAddress; 
unsigned char RetryLevel; 
unsigned char EncryptionStatus; 
unsigned char CommandDataLength; 
unsigned char CommandData[255]; 
unsigned char ResponseStatus; 
unsigned char ResponseDataLength; 
unsigned char ResponseData[255]; 
unsigned char IgnoreError; 
};

typedef UINT (__stdcall* DLLFUNC3)(SSP_COMMAND* cmd, SSP_COMMAND_INFO* sspInfo); DLLFUNC3 sspSendCommand = (DLLFUNC3)GetProcAddress(hInst, "SSPSendCommand");
P.D. También existe una dll hecha para C# .NET or Visual Basic .NET
Responder Con Cita
  #2  
Antiguo 30-09-2019
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Diego E. Ver Mensaje
Estoy realizando un proyecto Delphi, para el que necesito usar una dll hecha para C/C++ o Visual Basic 6, en la documentación de la dll no viene la forma de implementar en Delphi(no es sorpresa) ni describe los comandos dentro de ella como para hacer el típico procedimiento de:

Es la primera vez que voy a trabajar con dll's y ciertamente no se usar C++, se que la información va de casi a totalmente nula, pero alguno tiene alguna referencia de como trabajar dicha dll (o en general cualquier dll hecha en un lenguaje externo a Delphi).
Al final, da igual en qué esté hecha la DLL (o debería dar igual), la llamada desde tu programa es indiferente.

Cita:
Empezado por Diego E. Ver Mensaje
Adjunto un poco del código que viene en la documentación de la dll:
Código:
struct SSP_COMMAND {
SSP_FULL_KEY Key;
unsigned long BaudRate;
unsigned long Timeout;
unsigned char PortNumber;
unsigned char SSPAddress;
unsigned char RetryLevel;
unsigned char EncryptionStatus;
unsigned char CommandDataLength;
unsigned char CommandData[255];
unsigned char ResponseStatus;
unsigned char ResponseDataLength;
unsigned char ResponseData[255];
unsigned char IgnoreError;
};
typedef UINT (__stdcall* DLLFUNC3)(SSP_COMMAND* cmd, SSP_COMMAND_INFO* sspInfo); DLLFUNC3 sspSendCommand = (DLLFUNC3)GetProcAddress(hInst, "SSPSendCommand");
En este caso tienes varias cosas.
Primero debes tener definida la cabecera de la función a la que vas a llamar.
Código Delphi [-]
function sspSendCommand (cmd:SSP_COMMAND; sspInfo:SSP_COMMAND_INFO):Integer; stdcall; external 'itlsspproc.dll';

Como la cabecera necesita unos tipos "específicos" denerás tenerlos definidos en tu unidad (.PAS), así que debes "covertir" los tipos que ya te dan a Delphi.

En tu caso, por ejemplo, el tipo:

Código:
struct SSP_COMMAND {
SSP_FULL_KEY Key;
unsigned long BaudRate;
unsigned long Timeout;
unsigned char PortNumber;
unsigned char SSPAddress;
unsigned char RetryLevel;
unsigned char EncryptionStatus;
unsigned char CommandDataLength;
unsigned char CommandData[255];
unsigned char ResponseStatus;
unsigned char ResponseDataLength;
unsigned char ResponseData[255];
unsigned char IgnoreError;
};
Se traduce como:

Código Delphi [-]
type
  SSP_COMMAND = record
    Key: SSP_FULL_KEY;
    BaudRate: LongInt;
    Timeout: LongInt;
    PortNumber: Byte;
    SSPAddress: Byte;
    RetryLevel: Byte;
    EncryptionStatus: Byte;
    CommandDataLength: Byte;
    CommandData: Array[0..255-1] of Byte;
    ResponseStatus: Byte;
    ResponseDataLength: Byte;
    ResponseData: Array[0..255-1] of Byte;
    IgnoreError: Byte;
  end {SSP_COMMAND};

Algo similar debes hacer con el resto.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 30-09-2019
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Los otros tipos podrían ser algo así:


Código Delphi [-]
type
  SSP_FULL_KEY = record
    FixedKey: LongInt;
    EncryptKey: LongInt;
  end {SSP_FULL_KEY};

  SSP_PACKET = record
    packetTime: Word;
    PacketLength: Byte;
    PacketData: Array[0..255-1] of Byte;
  end {SSP_PACKET};


  SSP_COMMAND_INFO = record
    CommandName: PByte;
    LogFileName: PByte;
    Encrypted: Byte;
    Transmit: SSP_PACKET;
    Receive: SSP_PACKET;
    PreEncryptTransmit: SSP_PACKET;
    PreEncryptRecieve: SSP_PACKET;
  end {SSP_COMMAND_INFO};

  SSP_COMMAND = record
    Key: SSP_FULL_KEY;
    BaudRate: LongInt;
    Timeout: LongInt;
    PortNumber: Byte;
    SSPAddress: Byte;
    RetryLevel: Byte;
    EncryptionStatus: Byte;
    CommandDataLength: Byte;
    CommandData: Array[0..255-1] of Byte;
    ResponseStatus: Byte;
    ResponseDataLength: Byte;
    ResponseData: Array[0..255-1] of Byte;
    IgnoreError: Byte;
  end {SSP_COMMAND};
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 30-09-2019
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Supongo que si alguien más quiere mirar el tema, este documento le podría servir de ayuda.


http://www.marrginal.ru/files/cashma...ide%20v2.2.pdf


Si tienes algun otro link, estaría bien que lo añadieras.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 01-10-2019
Diego E. Diego E. is offline
Miembro
 
Registrado: mar 2018
Posts: 30
Poder: 0
Diego E. Va por buen camino
Antes que nada gracias por tomarte el tiempo de ver el tema y responder.
Comenzaré como dices con los encabezados del las funciones principales en el documento y de ahí me iré adentrando más en el tema, probando si lo que hago es correcto, tengo entendido que una vez logrando dicha instrucción ya sólo debo mandar llamar el método que me retornó el GetProcAddress y mandando como parámetos los tipos declarados con anterioridad. Cualquier cosa estaré reportándome de nuevo. Gracias.
Responder Con Cita
  #6  
Antiguo 06-10-2019
Diego E. Diego E. is offline
Miembro
 
Registrado: mar 2018
Posts: 30
Poder: 0
Diego E. Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje

Código Delphi [-]
function sspSendCommand (cmd:SSP_COMMAND; sspInfo:SSP_COMMAND_INFO):Integer; stdcall; external 'itlsspproc.dll';

Hola de nuevo, tengo algunas dudas más específicas acerca de este tema:

Tengo entendido que hay dos formas de usar las funciones dentro de la DLL(estática y dinámica), cuando intento llevar a cabo las siguientes lineas de C++ usando el dinámico tengo algo así:

Codigo de C++ a replicar(no tal cual, sólo lo que ocupo):
Código:
HINSTANCE hInst = LoadLibrary("ITLSSPProc.dll");
	if (hInst != NULL)
	{
		// Link function names

		// Opens the COM port
		OpenPort = (LPFNDLLFUNC1)GetProcAddress(hInst, "OpenSSPComPortUSB");
		if (OpenPort == NULL)
		{
			FreeLibrary(hInst);
			THREAD_UNLOCK
			return false;
		}
Yo hago algo así:
Código Delphi [-]
hInst := LoadLibrary('ITLSSPProc.dll');

    if hInst <> 0 then
    begin

      OpenPort := GetProcAddress(hInst, 'OpenSSPComPortUSB');
      if @OpenPort = nil then //Linea de la duda
      begin
        FreeLibrary(hInst);
        ShowMessage('No se pudo traer el OpenPort');
        Exit;
      end;

Pero aqui hay dos cosas, si en la línea de la duda pogo el @(que tengo entendido que es como usar un apuntador, pero no se) al evaluarlo me da nil (cosa que no debería pasar si funciona bien la linea del GetProcAddess), si le quito el arroba ni siquiera compila y me arroja el mensaje "Not enough actual parameters" que si no me equivoco es por que está intentando ejecutar la función(Cosa que no trato de hacer, yo sólo quiero saber si el GetProcAddess funcionó).

¿Saben que estoy haciendo mal o cual sería forma correcta de hacer el GetProcAddress?

El código completo es:
Código Delphi [-]
unit LibDLL;

interface

uses
  Vcl.Dialogs, SysUtils, Variants, Classes, Db, Forms, IniFiles, ADODB, Buttons,
  Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Controls, Windows;


Type

TSSP_FULL_KEY = record
  FixedKey: LongInt;
  EncryptKey: LongInt;
end {SSP_FULL_KEY};

SSP_PACKET = record
  packetTime: Word;
  PacketLength: Byte;
  PacketData: Array[0..255-1] of Byte;
end {SSP_PACKET};

TSSP_COMMAND = record
  Key: TSSP_FULL_KEY;
  BaudRate: LongInt;
  Timeout: LongInt;
  PortNumber: Byte;
  SSPAddress: Byte;
  RetryLevel: Byte;
  EncryptionStatus: Byte;
  CommandDataLength: Byte;
  CommandData: Array[0..255-1] of Byte;
  ResponseStatus: Byte;
  ResponseDataLength: Byte;
  ResponseData: Array[0..255-1] of Byte;
  IgnoreError: Byte;
end {SSP_COMMAND};

TSSP_KEYS = Record
  Generator: int64;
  Modulus: int64;
  HostInter: int64;
  HostRandom: int64;
  SlaveInterKey: int64;
  SlaveRandom: int64;
  KeyHost: int64;
  KeySlave: int64;
End;

TSSP_COMMAND_INFO = record
  CommandName: PByte;
  LogFileName: PByte;
  Encrypted: Byte;
  Transmit: SSP_PACKET;
  Receive: SSP_PACKET;
  PreEncryptTransmit: SSP_PACKET;
  PreEncryptRecieve: SSP_PACKET;
end {SSP_COMMAND_INFO};

TPORT_CONFIG = Record
  NumberOfPorts: String;
  LogFileName: PChar;
  Encrypted: String;
End;

type
  TOpenPort = function (cmd: TSSP_COMMAND): Integer;
//  function OpenPort (cmd: TSSP_COMMAND): Integer; cdecl; external 'ITLSSPProc.dll';
  function SSPSendCommand (cmd:TSSP_COMMAND; sspInfo:TSSP_COMMAND_INFO):Integer; stdcall; external 'ITLSSPProc.dll';


  Function VerificarDLL(): Boolean;
  Procedure InitConfSPO();
  Procedure InitialiseLibrary();


var
  cmd: TSSP_COMMAND;
  keys: TSSP_KEYS;
  sspKey: TSSP_FULL_KEY;
  info: TSSP_COMMAND_INFO;

  OpenPort: function (cmd: TSSP_COMMAND): Integer; stdcall;

  hInst: THandle;

implementation

//------------------------------------------------------------------------------

Function VerificarDLL(): Boolean;
var
  fileName:String;

begin

  Result := False;
  fileName := 'ITLSSPProc.dll';

  if fileexists(fileName) then
  begin
    Result := True;
  end
  else ShowMessage(fileName+' does not exist');

end;

//------------------------------------------------------------------------------

Procedure InitConfSPO();
begin

  InitialiseLibrary

end;

Procedure InitialiseLibrary();
begin

  if VerificarDLL then
  begin

    hInst := LoadLibrary('ITLSSPProc.dll');

    if hInst <> 0 then
    begin

      OpenPort := GetProcAddress(hInst, 'OpenSSPComPortUSB');
      if OpenPort = nil then
      begin
        FreeLibrary(hInst);
        ShowMessage('No se pudo traer el OpenPort');
        Exit;
      end;

    end
    else ShowMEssage('No se pudo instanciar la DLL');

  end;

end;


end.

He intentado con diferentes combinaciones(estáticas y dinámicas) pero no funciona, ahora estoy tratando de apegarme lo más posible a la forma C++ que coloqué.

¿Alguna idea? Si requieren el código y archivos que estoy tratando de usar se los puedo enviar por e-mail
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Llamar Aplicacion externa desde Delphi Fmx Androit ASAPLTDA FireMonkey 4 08-08-2018 09:01:03
abrir aplicación externa desde delphi y detectar su cierre petete2008 API de Windows 2 10-02-2012 11:44:23
Llamar a otra aplicacion externa a delphi... daniel43 Varios 2 29-12-2010 01:30:44
Delphi - HotKey de aplicación externa fdanielc Lazarus, FreePascal, Kylix, etc. 2 03-12-2008 20:12:11
Usar una aplicación externa desde Delphi erika.martinez Varios 9 14-04-2005 18:10:22


La franja horaria es GMT +2. Ahora son las 00:56:35.


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
Copyright 1996-2007 Club Delphi