【发布时间】:2016-08-11 21:40:06
【问题描述】:
我有一个由第 3 方公司提供的 DLL,当从 Delphi 2007 调用时,它工作得非常好。以下代码是在 Delphi 2007 中如何使用 DLL 的示例:
Procedure XC_eXpressLink(hHandle: Hwnd; Parameters: pChar; Result: pChar); stdcall; external 'XCClient.dll';
以下是该过程的调用方式:
procedure TForm1.Button1Click(Sender: TObject);
var Result: array[0..2000] of char;
sParams: String;
begin
sParams := RemoveCRLF(memoParameters.Text); //Remove TMemo CR/LF
XC_eXpressLink(Handle, pChar(sParams), Result);
memoResults.Text := String(Result);
end;
我不确定 DLL 是用什么编译的,但我假设它需要的是 ansi 而不是 unicode。在Delphi XE5中将代码转换为ansi后,现在代码如下:
Procedure XC_eXpressLink(hHandle: Hwnd; Parameters: pAnsiChar; Result: pAnsiChar); stdcall; external 'XCClient.dll';
和
procedure TForm1.Button1Click(Sender: TObject);
var Result: array[0..2000] of Ansichar;
sParams: AnsiString;
begin
sParams := RemoveCRLF(memoParameters.Text); //Remove TMemo CR/LF
XC_eXpressLink(Handle, pAnsiChar(sParams), Result);
memoResults.Text := AnsiString(Result);
end;
memoParameters 是窗体上的一个 TMemo,它为 dll 过程提供参数。 RemoveCRLF 是一个从 memoParameters 中删除任何回车和换行的函数。 MemoResults 是窗体上的另一个 TMemo,提供 dll 过程的返回结果。
当更改的代码在 Delphi XE5 中运行时,我遇到了访问冲突。由于我将所有参数都更改为使用ansi,所以dll不应该获得与以前相同的参数格式吗?难道我做错了什么?我能否让这个较旧的编译 DLL 在 Delphi XE5 中工作?
【问题讨论】:
-
看起来不错。这真的是所有的代码。你怎么知道2000个字符就够了。
-
提供 DLL 的公司提供了一个示例 Delphi 应用程序,展示了如何调用他们的 DLL。他们将其定义为 2000 个字符。他们还提供了一份说明手册,其中指出:“在调用函数之前,必须将 Result 变量缓冲区预分配至少 2000 个字节。”
-
@RemyLebeau 感谢您的信息。我没有意识到其他人也有同样的问题。调用dll程序后,弹出第三者输入信用卡信息的表单。然后,当鼠标经过信用卡表单上的任何输入字段时,就会发生 AV。 AV 错误是“地址 6948540B 的访问冲突。读取地址 6948540B。”此外,正如您在上面的链接和我的 cmets 中提到的,第 3 方请求至少 2000 字节的预分配变量缓冲区。我已尝试增加数量,但仍会导致相同的 AV 错误。
-
@RonSwingler 那么问题出在 DLL 本身内部。请联系 DLL 供应商寻求帮助。或者使用调试器进入 DLL 机器代码。也许它正在向您的 HWND 发送一条未正确处理的奇怪消息。或者它可能取决于未正确设置的 CPU 标志。 DLL 确实处理货币值,因此可能存在浮点不兼容。 AV 是由试图从自己的地址读取的代码地址引起的,这有点奇怪。这可能意味着动态分配的代码存根/代理中存在错误。
标签: delphi unicode delphi-xe5 delphi-2007 ansi