// delphi代码(delphi版本:Turbo Delphi Explorer(它是Delphi 2006))
function GetLoginResult:PChar;
begin
result:=PChar(LoginResult);
end;
Run Code Online (Sandbox Code Playgroud)
//使用上面的delphi函数的C#代码(我使用的是unity3d,在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
Run Code Online (Sandbox Code Playgroud)
在C#中使用该功能的正确方法是什么?
(也用于delphi,代码就像if(event = 1)和(tag = 10)then writeln('Login result:',GetLoginResult);)
字符串的内存由Delphi代码拥有,但是你的p/invoke代码将导致marshaller调用CoTaskMemFree该内存.
你需要做的是告诉编组人员它不应该对释放内存负责.
[DllImport ("ServerTool")]
private static extern IntPtr GetLoginResult();
Run Code Online (Sandbox Code Playgroud)
然后使用Marshal.PtrToStringAnsi()将返回值转换为C#字符串.
IntPtr str = GetLoginResult();
string loginResult = Marshal.PtrToStringAnsi(str);
Run Code Online (Sandbox Code Playgroud)
您还应通过声明Delphi函数来确保调用约定匹配stdcall:
function GetLoginResult: PChar; stdcall;
Run Code Online (Sandbox Code Playgroud)
虽然这种调用约定不匹配对于没有参数和指针大小的返回值的函数无关紧要.
为了使所有这些工作,Delphi字符串变量LoginResult必须是一个全局变量,以便在GetLoginResult返回后其内容有效.