Delphi-外部DLL和GetProcAddress

时间:2019-03-22 16:14:36

标签: delphi dll

我第一次必须从Delphi调用外部DLL。 这是DLL附带的体重秤。 首先,我想连接到这个秤。 这是我的代码:

unit XOdeca;

interface
[...]

type
  TXFSOdecaConnected = function: boolean; stdcall;
  TXFSOdecaConnect = procedure (SERIAL_PORT: PChar); stdcall;

  TXOdeca = class
  protected
    FOdecaDllHandle: THandle;
    FFLBilanciaConnessa: boolean;

  public
    constructor Create;
    destructor Destroy; override;

    procedure LoadOdeca;
  end;


implementation

uses
  System.UITypes;

[...]   

procedure TXOdeca.LoadOdeca;
const
    LibName = 'OdecaDeviceControl.dll';
var
    libreria: string;
    fnIsScanLibraryRegistered: TXFSOdecaConnected;
    fnConnectOdeca: TXFSOdecaConnect;
begin

    if FOdecaDllHandle = 0 then
    begin
        libreria := ExtractFilePath( Application.ExeName ) + LibName;
        if not FileExists( libreria ) then
            raise Exception.Create( 'Non posso aprire la libreria ' + libreria );

        try
            FOdecaDllHandle := LoadLibrary( @libreria[1] );
            if FOdecaDllHandle = 0 then
                raise Exception.Create('Errore in caricamento libreria "' + LibName + '"' );

            @fnConnectOdeca := GetProcAddress( FOdecaDllHandle, 'Odeca.SerialDevice.Connect');
            if not Assigned( @fnConnectOdeca ) then
                raise Exception.Create( 'Impossibile trovare il punto di ingresso "fnConnectOdeca" in "' + LibName + '"' );


            @fnIsScanLibraryRegistered := GetProcAddress( FOdecaDllHandle, 'Odeca.SerialDevice.Connected');
            if not Assigned( @fnIsScanLibraryRegistered ) then
                raise Exception.Create( 'Impossibile trovare il punto di ingresso "FSIsScanLibraryRegistered" in "' + LibName + '"' );

            FFLBilanciaConnessa := fnIsScanLibraryRegistered;

        except
        [...]    
        end;
    end;
end;


end.

我可以正确加载库(FOdecaDllHandle的值不同于0),但是我无法连接到库中的任何函数或过程,GetProcAddress始终返回0。

从库随附的文档中,过程名称正确。

该库还附带了VB.net和C#中的两个工作示例,它们都声明了(VB.net)之类的对象

Private odecaDevice As New Odeca.SerialDevice

但是我认为这在Delphi中是不可能的,因为我没有添加对库对象的引用。

它与库中使用的点符号有关系吗? (例如,根据体重计的连接类型,使用每个程序都有两个版本,例如Odeca.SerialDevice.Connect和Odeca.NetworkDevice.Connect)。

非常感谢你, 法比奥

---更新29/03/2019

按照此链接Work around with Delphi DLL上的示例,我创建了以下OdecaWrapper.dll:

procedure CONNECT; export;
var
    adll: Thandle;
    afunc: function:Boolean;
begin
    adll:=LoadLibrary('OdecaDeviceControl.dll');
    afunc:= GetProcAddress(adll,'Odeca.SerialDevice.Connect');
    afunc;
    FreeLibrary(adll);
end;

    exports
        CONNECT;

在我的Delphi代码中,定义。

procedure CONNECT; stdcall; external 'OdecaWrapper.dll';

,没有实现。 在同一个Delphi单元中,我有一个调用此外部过程的过程


procedure TXOdeca.LoadOdeca;
begin
    try
        CONNECT;
        [missing]
    except
        on E:Exception do
        begin
            MessageDlg( E.Message, mtWarning, [mbOK], 0 );
        end;
    end;
end; 

当我进入过程的CONNECT命令时,我得到的只是访问冲突,我在做什么错?

2 个答案:

答案 0 :(得分:0)

不可能直接从delphi与该.NET库进行通信。

我让另一个程序员创建了一个.NET控制台应用程序(OdecaReader.exe),该应用程序调用该库,从秤中读取重量,并将其写入临时.txt。

从Delphi中,我调用此OdecaReader.exe,然后读取临时文件的内容。

答案 1 :(得分:0)

可以使用 .NET DLL。我实际上使用它 - 对于 C#,请参阅 NuGet 上的非托管导出。您可以编写一个包装 DLL 并仅使用您需要的功能。