は、次のC++/CLIのコードフラグメントを考えてみましょう:オブジェクトは実行中にガベージコレクトされますか?
public ref class MyData
{
private:
UnmanagedObject* pobj;
public:
MyData()
{
pobj = ... // acquire unmanaged pointer
}
!MyData()
{
delete pobj; // finalizer
pobj = NULL;
}
void DoSomething()
{
// next line calls a native method that has no knowledge of .NET
CallToNativeMethod(data->pobj);
}
static void Test()
{
MyData^ data = gcnew MyData();
data->DoSomething()
}
}
このクラスは、いくつかの非管理APIの.NETラッパーを表します。私のプロジェクトでは、現在、トレースするのが難しいバグを扱っています。MyData
のインスタンスは、DoSomething()
の実行中にガベージコレクションされているようです。ここで私は起こる信じるものである:(!)
MyData
DoSomething()
と呼ばれるDoSomething()
インスタンスメソッドのインスタンスを作成すると呼ばれる静的メソッドTest()
は、ネイティブメソッド- しばらく呼び出しますネイティブメソッドが実行されているときに、ガベージコレクタが
MyData
のインスタンスを収集し、ファイナライザを呼び出す - ファイナライザは、ネイティブの私によって使用される
pobj
を削除します。- が実際に可能上記のようなシナリオです:THOD まだプログラムが
私の2つの質問がクラッシュ...
- まあを実行していますか?インスタンスメソッドがまだ実行されている間に、オブジェクトがファイナライズされるという事実をかなり引き継ぐことはできません。
- この問題を解決するには、どのような方法が良いですか?そうするための "安全")? のインスタンス変数の後にネイティブメソッドが実行された場合、そのトリックは変更されますが、それはアドホックです。
EDIT(追加情報):ネイティブメソッドからバブルアップ、及びTest()
にtry..catch
によって捕捉することができるAccessViolationException
を持つコードがクラッシュ。デバッグのために、私は、次の実行順序を明らかにし、ロギング呼び出しのカップルを、挿入:
オブジェクトがガベージコレクションされていることを確認していますか? –
MyDataのインスタンスが収集される可能性はありません。結局それはTestメソッドに根ざしています。例外は何を言いますか? –
@Matt:ポストを編集していくつかの情報を追加しました –