dataol
dataol

Reputation: 1009

Error calling DLL with Unicode Delphi

I have a DLL with this function signature:

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

This is the sample VB.NET code from the manual of the dll:

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)

This is my Delphi code:

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;

This code works well in Delphi 7, but not works in Delphi XE. It always returns "Error". How to make this code works in Delphi XE?

Upvotes: 2

Views: 2188

Answers (1)

Rob Kennedy
Rob Kennedy

Reputation: 163357

If the DLL was written in Delphi 7, then you cannot use that DLL from Delphi XE. Even if you change the string parameters to AnsiString to make the character sizes the same, you're still stuck with the fact that the internal structure of strings changed somewhere between those versions, so the AnsiString you send from the Delphi XE code will not look the way the Delphi 7 code expects an AnsiString to look.

If you have the power to change and recompile the DLL, you should make the parameters be PAnsiChar instead, just like you'd see from nearly any other DLL on Windows. Also remember to change the final PChar parameter to PAnsiChar.


If the DLL was written in some non-Delphi language, then you might be able to fix it simply by changing the function signature. Non-Delphi languages don't have Delphi's string type, so the declaration was wrong all the time; you were just lucky when it worked from Delphi 7. Change all the parameters to have type PAnsiChar (including the final parameter); then they'll match the char* type they probably have from the original C code.

Upvotes: 7

Related Questions