gpt4 book ai didi

delphi - 具有回调过程的动态 DLL - Delphi

转载 作者:行者123 更新时间:2023-12-03 18:20:25 30 4
gpt4 key购买 nike

我想动态加载 DLL 函数。该函数在静态 DLL 模式下运行良好。但我无法让它在动态模式下工作。

type
TCallBackProcedure = procedure(StringValue: PAnsiChar;
IntegerValue: integer)stdcall;

type
TOpenPort = function(dnum: integer;
CallBackString: TCallBackProcedure): integer;


function xOpenPort(dnum: integer; CallBackString: TCallBackProcedure): integer;

const

tDLL = 'myDll.dll';

function OpenPort(dnum: integer; CallBackString: TCallBackProcedure): integer;
stdcall; external tDLL;

procedure CallBackString(StringValue: PAnsiChar; integerValue : Integer) stdcall;
begin
strAA := StringValue; // string
SLb.Add(strAA); // StringList
end;

静态模式下运行没有问题。

 iOutput := OpenPort(9, @CallBackString); // working fine

这是我在动态加载中调用它的努力;

function xOpenPort(dnum: integer; CallBackString: TCallBackProcedure): integer;
var
hDll: THandle;
xOpen: TOpenPort;
begin
try
hDll := loadLibrary(tDLL);
if hDll <> 0 then
begin
//load dll OK
@xOpen := getProcAddress(hDll, 'OpenPort');
if @xOpen <> nil then
begin
Result := 5;
// I see also function is loaded
Result := xOpen(dnum, @CallBackString);
prn(IntToStr(Result));
end;
end;
finally
freeLibrary(hDll);
end;
end;

我如何打电话:

iOutput := xOpenPort(9, @CallBackString);  // access violation

我遇到了访问冲突。如何在动态加载中调用这样的 DLL?我在静态模式下有很多这样的功能。

最佳答案

您对 TOpenPort 类型的定义缺少 stdcall 调用约定,就像您对 OpenPort() 的静态定义所使用的那样:

type
TOpenPort = function(dnum: integer; CallBackString: TCallBackProcedure): integer; stdcall;

如果没有该调用约定,则使用 Delphi 的默认register 调用约定,从而导致参数值通过 CPU 寄存器传递,而不是在 DLL 函数期望找到它们的调用堆栈上传递。

此外,在 xOpenPort() 函数中,将 CallBackString 参数传递给 xOpen< 时,请勿使用 @ 运算符。该参数已经是正确的类型。您需要传递它的值(即回调函数的内存地址),而不是参数本身的内存地址,因此只需将其按原样传递给 xOpen:

Result := xOpen(dnum, CallBackString);

关于delphi - 具有回调过程的动态 DLL - Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57764257/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com