我正在尝试使用.net dll中的方法将其导入我的delphi脚本
function GetAnswer() : string; external 'PixelPatternCaptcha.dll';
begin
Print(GetAnswer)
end.
我在第4行得到错误
Print(GetAnswer)
错误代码:
Module: "", Line: 3, Message: Access violation at address 00000000. Read of address 00000000
我认为该方法没有找到DLL,但我不知道如何为它指定路径。目前,我将dll放在与脚本相同的文件夹中。
修改
实际上,它正在被调用,因为当我尝试删除dll时它告诉我我的.EXE已经打开它。所以,我可以调用我的DLL但得到同样的错误。
EDIT2:
目前正在努力:
procedure GetAnswer(out codeResult: WideString); stdcall; external 'PixelPatternCaptcha.dll';
var r : WideString;
begin
print(GetAnswer(r));
end.
答案 0 :(得分:1)
使用DLL Search Order找到DLL。在您的情况下,由于程序正在执行,因此会找到并加载DLL。确实找到并导入了该函数。
因此,运行时错误是由于代码中的缺陷造成的。问题是使用string
作为返回值类型。除了两个DLL都使用相同版本的Delphi构建并共享相同的内存管理器之外,这对于导入的DLL永远不会有效。这不是这种情况,您使用Robert Giesecke的UnamagedExports工具导入.net DLL。
您需要更改C#和Delphi代码才能使用有效的interop类型。最方便的是COM BSTR类型,在Delphi中称为WideString
。
在C#端看起来像这样:
[DllExport]
public void GetAnswer(
[MarshalAs(UnmanagedType.BStr)] out string result
)
{
result = "foo";
}
在Delphi方面,您可以像这样导入:
procedure GetAnswer(out result: WideString); stdcall; external 'PixelPatternCaptcha.dll';
我在这里使用out
参数而不是返回值的原因在这里解释:
Why can a WideString not be used as a function return value for interop?