我在以下情况中遇到“灾难性故障”错误。
type
TGetDoubleValue = function (var ID: Integer): Double; safecall;
....
....
var
GetDoubleValue: TGetDoubleValue;
.....
.....
LibHandle := LoadLibrary('GetDoubleValue.dll');
@GetDoubleValue := GetProcAddress(LibHandle, 'getDoubleValue');
if not (@GetDoubleValue = nil) then
begin
myDouble := GetDoubleValue(ID);
end
else
RaiseLastOSError;
调用此函数时,我在“myDouble := GetDoubleValue(ID);
”行上收到错误。
答案 0 :(得分:4)
这个错误几乎肯定是因为调用约定或参数列表不匹配。
从DLL导入的函数真的不是safecall
。该调用约定与COM方法一起用于执行HRESULT
参数列表重写。更有道理的是,调用约定是stdcall
,但你必须检查。您还应该仔细检查参数和返回类型是否完全匹配。
如果你不能自己解决,那么请从DLL源代码(或文档)中添加函数声明的问题。
我也不喜欢使用带有函数指针的@
。它往往会导致编译器可能发现的错误。我会写这样的代码:
LibHandle := LoadLibrary('GetDoubleValue.dll');
Win32Check(LibHandle<>0);
GetDoubleValue := GetProcAddress(LibHandle, 'getDoubleValue');
Win32Check(Assigned(GetDoubleValue));
myDouble := GetDoubleValue(ID);
FWIW,我是Win32Check
的忠实粉丝,因为它从高级代码中移除了分支,这使得它更容易阅读。