【问题标题】:Pre-unicode compiled DLL gives access violations when calling from Delphi XE5从 Delphi XE5 调用时,预 unicode 编译的 DLL 会出现访问冲突
【发布时间】: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 个字节。”
  • 显示的经 Ansi 转换的代码在技术上是正确的,它没有任何错误会导致 AccessViolation IF 1) DLL 没有溢出缓冲区,并且 2 ) 缓冲区输出始终以空值结尾。另一方面,这不是第一次报告与在 XE5 中使用 XC_eXpressLink() 相关的 AccessVioation(请参阅 thisthis)。 实际 AV 错误说明了什么?你试过调试了吗?
  • @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


【解决方案1】:

我联系了 OpenEdge 公司,该公司为 X-Charge(用于信用卡集成)提供 dll。要解决此问题,Handle 的值必须为 0,并且您必须将 /IGNOREHANDLEPARAMETER 添加到发送到dll。注意,此参数仅适用于完整版 XC8.1.1.6.exe 安装或更高版本。

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(0, pAnsiChar(sParams), Result);
  memoResults.Text := AnsiString(Result);
end;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多