2

C++ 側に CString cs があり、C# 側に IntPtr ip があります。これには、マーシャリング メカニズムによる cs の値が含まれています。

次に、必要な文字列を Marshal.PtrToStringAnsi(ip) として取得するだけで、すべて正常に動作しますが、ip によって占有されている管理されていないメモリ、つまり cs を削除するにはどうすればよいでしょうか?

4

2 に答える 2

1

アンマネージコードによって割り当てられたアンマネージメモリは、アンマネージコードによってのみ解放できます。したがって、割り当てられた文字列へのポインタを取得してメモリを解放する別のアンマネージ関数を追加する必要があります。この関数は、文字列の処理が終了したら、マネージコードから呼び出す必要があります。

例:

class Program
{
    [DllImport("test.dll")]
    static extern IntPtr GetString();

    [DllImport("test.dll")]
    static extern IntPtr FreeString(IntPtr ptr);

    static void Main()
    {
        IntPtr ptr = GetString();
        try
        {
            var str = Marshal.PtrToStringAnsi(ptr);
            // work with the string
        } 
        finally 
        {
            if (ptr != IntPtr.Zero)
            {
                FreeString(ptr);
            }
        }
    }
}
于 2010-04-28T15:07:45.977 に答える
1

できません。CString インスタンスを作成するために、アンマネージ コードがどのアロケーターを使用したかわかりません。さらに、CString デストラクタを呼び出す必要があり、そのアドレスを取得できません。

この CString オブジェクトが、C# から呼び出した C++ 関数の関数戻り値として返された場合、あなたは水に沈んでいます。あなたの質問からは明らかではありません。制御不能なメモリリークが発生します。この問題を修正するには、C++/CLI で記述されたラッパーが必要です。関数の戻り値として返される文字列は、P/Invoke マーシャラーによって適切にクリーンアップされるように、CoTaskMemAlloc() によって割り当てられる必要があります。これを行う C++ コードはありません。

于 2010-04-28T15:16:56.290 に答える