4

// delphi 代码(delphi 版本:Turbo Delphi Explorer(它是 Delphi 2006))

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

//C#代码使用上面的delphi函数(我用的是unity3d,inside,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

在 C# 中使用该函数的正确方法是什么?

(也用于delphi,代码类似于 if (event=1) and (tag=10) then writeln('Login result: ',GetLoginResult); )

4

1 回答 1

8

字符串的内存归您的 Delphi 代码所有,但您的 p/invoke 代码将导致编组器调用CoTaskMemFree该内存。

你需要做的是告诉编组器它不应该负责释放内存。

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

然后用于Marshal.PtrToStringAnsi()将返回的值转换为 C# 字符串。

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

您还应该通过将 Delphi 函数声明为来确保调用约定匹配stdcall

function GetLoginResult: PChar; stdcall;

尽管这种调用约定不匹配对于没有参数和指针大小的返回值的函数来说并不重要。

为了使所有这些工作,Delphi 字符串变量LoginResult必须是一个全局变量,以便其内容在GetLoginResult返回后有效。

于 2012-06-24T07:20:22.363 回答