2

我有一个带有这个函数签名的 DLL :

function KP_RecuperarDadosFabricante(EnderecoIp, ChaveAcesso, 
  Porta: string; Return: PAnsiChar): Integer; stdcall; external 'Key.dll';

这是 dll 手册中的示例 VB.NET 代码:

Dim ret As Integer 
Dim ptrStr As IntPtr 
Dim DadosFab As String 

ptrStr = System.Runtime.InteropServices.Marshal.AllocHGlobal(256) 
ret = KP_RecuperarDadosFabricante("192.168.1.201", "0", "4370", ptrStr) 
DadosFab = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptrStr)
System.Runtime.InteropServices.Marshal.FreeHGlobal(ptrStr)

这是我的德尔福代码:

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  Return: string;
  pReturn: PAnsiChar;
begin
  GetMem(pReturn, 512);
  FillChar(pReturn^, 512, 0);
  Memo1.Text:='';
  if KP_RecuperarDadosFabricante("192.168.1.201", "0", "4370", pReturn) = 1 then
  begin
    Return := StrPas(pReturn);
    ShowMessage(Return);
  end
  else
  begin
    ShowMessage('Error');
  end;
end;

此代码在 Delphi 7 中运行良好但在 Delphi XE 中不起作用。它总是返回“错误”。如何使此代码在Delphi XE中工作?

4

1 回答 1

7

如果 DLL 是用 Delphi 7 编写的,那么您不能使用 Delphi XE 中的 DLL。即使您更改string参数以AnsiString使字符大小相同,您仍然会遇到这样一个事实,即字符串的内部结构在这些版本之间的某个地方发生了变化,因此AnsiString您从 Delphi XE 代码发送的代码不会看起来像Delphi 7 代码需要一个AnsiString外观。

如果您有权更改和重新编译 DLL,则应PAnsiChar改为使用参数,就像您在 Windows 上几乎所有其他 DLL 中看到的一样。还要记住将最终PChar参数更改为PAnsiChar.


如果 DLL 是用某种非 Delphi 语言编写的,那么您可以简单地通过更改函数签名来修复它。非Delphi语言没有Delphi的string类型,所以声明一直是错误的;当它从 Delphi 7 开始工作时,您很幸运。将所有参数更改为具有类型PAnsiChar(包括最终参数);然后它们将与char*原始 C 代码中可能具有的类型相匹配。

于 2013-03-15T21:07:51.707 回答