delphi - 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 命令时,我得到的只是访问冲突,我做错了什么?
解决方案
无法直接从 delphi 与此 .NET 库进行通信。
我让另一个程序员创建了一个 .NET 控制台应用程序 (OdecaReader.exe),该应用程序调用该库,从秤中读取重量,并将其写入临时 .txt。
在 Delphi 中,我调用了这个 OdecaReader.exe,然后我读取了临时文件的内容。
推荐阅读
- swift - 带有请求参数和标头的分段上传 (Alamofire)
- php - 为什么我的下拉列表在提交后会重置?
- python - 有条件地遍历染色体并在一个数据帧中定位到染色体和另一个数据帧中的间隔
- node.js - 当我们开始运行python代码时如何让nodejs自动运行
- ios - 为什么不出现 TableView、TableCell?
- r - 我有 ID、purchaseate、purchaseprice 列。我必须获得 6 月份总购买价格低于 5 月份总购买量 50% 的 ID
- algorithm - 合并排序比较
- rxjs - 什么是patch operator,patch的含义是什么
- quickbase - 如何计算 QuickBase 中最大值的平均值?
- php - 导出声明只能出现在模块的顶层