2013-05-13 63 views
6

私はマネージSystem.ActionをC++/CLIプロジェクト内のアンマネージstd ::関数に変換しています。コールバックを使用した後に、指定したIntPtrをリリースする必要がありますか、それとも不要ですか?Marshal :: GetFunctionPointerForDelegate:その結果を公開する必要がありますか?

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? 
} 

答えて

6

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

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

GC::KeepAlive(callback); 

コールバックのみ限り、execute()メソッドが実行されているとして行われることを前提に。アンマネージコードがこのメソッド呼び出しを超えて関数ポインタを格納する場合、デリゲートオブジェクトをどこかに格納して有効にしなければなりません。

+0

m_nativeObject-> Execute(wrappedCallback)が同期していても、 – Notoriousxl

+5

スレッドはあなたの日を台無しにするでしょう。まあ、週。 –

2

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

関連する問題