Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call this delphi .dll function from C#?

Tags:

c#

pinvoke

delphi

// delphi code (delphi version : Turbo Delphi Explorer (it's Delphi 2006))

function GetLoginResult:PChar;
   begin
    result:=PChar(LoginResult);
   end; 

//C# code to use above delphi function (I am using unity3d, within, C#)

[DllImport ("ServerTool")]
private static extern string GetLoginResult();  // this does not work (make crash unity editor)

[DllImport ("ServerTool")] 
[MarshalAs(UnmanagedType.LPStr)] private static extern string GetLoginResult(); // this also occur errors

What is right way to use that function in C#?

(for use in also in delphi, code is like, if (event=1) and (tag=10) then writeln('Login result: ',GetLoginResult); )

like image 420
creator Avatar asked Feb 20 '23 01:02

creator


1 Answers

The memory for the string is owned by your Delphi code but your p/invoke code will result in the marshaller calling CoTaskMemFree on that memory.

What you need to do is to tell the marshaller that it should not take responsibility for freeing the memory.

[DllImport ("ServerTool")] 
private static extern IntPtr GetLoginResult();

Then use Marshal.PtrToStringAnsi() to convert the returned value to a C# string.

IntPtr str = GetLoginResult();
string loginResult = Marshal.PtrToStringAnsi(str);

You should also make sure that the calling conventions match by declaring the Delphi function to be stdcall:

function GetLoginResult: PChar; stdcall;

Although it so happens that this calling convention mis-match doesn't matter for a function that has no parameters and a pointer sized return value.

In order for all this to work, the Delphi string variable LoginResult has to be a global variable so that its contents are valid after GetLoginResult returns.

like image 57
David Heffernan Avatar answered Feb 23 '23 10:02

David Heffernan