首页 > 解决方案 > Delphi - 外部 DLL 和 GetProcAddress

问题描述

我第一次必须从 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

按照此链接中的示例使用 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 命令时,我得到的只是访问冲突,我做错了什么?

标签: delphidll

解决方案


无法直接从 delphi 与此 .NET 库进行通信。

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

在 Delphi 中,我调用了这个 OdecaReader.exe,然后我读取了临时文件的内容。


推荐阅读