从外部调用DLL时,代码从何处加载DLL

时间:2017-03-27 15:18:32

标签: delphi

我正在尝试使用.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.

1 个答案:

答案 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?