// delphi代码(delphi版本:Turbo Delphi Explorer(它是Delphi 2006))
function GetLoginResult:PChar;
begin
result:=PChar(LoginResult);
end;
//使用上面的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
在C#中使用该功能的正确方法是什么?
(也用于delphi,代码就像, if(event = 1)和(tag = 10)then writeln('Login result:',GetLoginResult); )
答案 0 :(得分:8)
字符串的内存由Delphi代码拥有,但是你的p / invoke代码将导致marshaller在该内存上调用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
返回后其内容有效。