4

// delphi コード (delphi バージョン : Turbo Delphi Explorer (Delphi 2006 です))

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

// 上記の Delphi 関数を使用する C# コード (C# 内で unity3d を使用しています)

[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#でその関数を使用する正しい方法は何ですか?

(デルファイでも使用する場合、コードは 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 に答える