7

C++/CLI プロジェクト内でマネージド System.Action をアンマネージド std::function に変換しています。コールバックを使用した後、指定された IntPtr を解放する必要がありますか?それとも不要ですか?

void MyClass::Execute(System::Action^ callback)
{           

    IntPtr callbackPtr = Marshal::GetFunctionPointerForDelegate(callback);
    std::function<void (void)> nativeCallback = static_cast<void (__stdcall *) (void)>(callbackPtr.ToPointer());

    m_nativeObject->Execute(wrappedCallback);

    // should I release callbackPtr here?
}
4

3 に答える 3

7

いいえ。これを行う Marshal クラス メソッドはありません。動的に生成されるすべてのコードと同様に、このメソッドによって作成されるサンクは AppDomain に関連付けられ、AppDomain がアンロードされるとアンロードされます。

これはデリゲート オブジェクトには当てはまらないことに注意してください。通常のガベージ コレクション ルールが適用されます。そして、注意が必要です。サンクはそれを維持しません。これはコードのバグです。ネイティブ コードの実行中にデリゲートが収集される可能性があります。このコード行をメソッドの最後に追加する必要があります。

GC::KeepAlive(callback);

コールバックは Execute() メソッドが実行されている間だけ行われるという前提で。アンマネージ コードがこのメソッド呼び出しを超えて関数ポインターを格納する場合は、デリゲート オブジェクトを有効に保つためにどこかに格納する必要があります。

于 2013-05-14T00:50:07.933 に答える
2

ポインターを解放する必要はありません。関数へのポインタは既にあります (マシンのアーキテクチャに応じて 32/64 ビット サイズになります)。.net フレームワーク インフラストラクチャがポインターを実行するためにさらに何かを必要とする場合、それはすべてのメソッドで同じであるため、静的に割り当てられます (状態なし)。

于 2013-05-13T16:01:56.210 に答える