Error calling DLL with Unicode Delphi

delphi, dll, parameter-passing, string, unicode

Solution

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.

Problem

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?

Original source