私はC++/CLIを使用していくつかのマネージラッパーを書いています。問題は、管理されていないメンバーを使用しているときに、GCがオブジェクトを破棄することがあることです。(この動作は非常識だと思いますが、これは別のトピックです)。詳細については、以下を参照してください。
オブジェクトがまだ使用されている間にファイナライザーが起動しました http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx
私が探しているのは、電話をかけるのに便利な方法です。
GC::KeepAlive(this);
すべてのメソッドの最後に。単純な古いvoidメソッドの場合は十分に簡単ですが、値を返すメソッドの場合は少し注意が必要です。
int ComputeInt() {
return m_unmanagedMember->LongRunningComputation();
}
次のように変換する必要があります:
int ComputeInt() {
int tmp = m_unmanagedMember->LongRunningComputation();
GC::KeepAlive(this);
return tmp;
}
これは私には少し醜いように見えます。
dtorでGC::KeepAliveを呼び出すガードクラスを検討しましたが、少し過剰に見えるすべてのメソッドでctorとdtorの呼び出しが発生します。
一時変数を回避できるC++の魔法はありますか?
編集
私は、try +が最終的に私のためにトリックを行うことに気づきました。つまり、次のようになります。
int ComputeInt() {
try {
return m_unmanagedMember->LongRunningComputation();
} finally {
GC::KeepAlive(this);
}
}
最後に、これを処理するマクロを実装しました。
#define KEEPALIVE_RETURN(x) try {\
return x;\
} finally { System::GC::KeepAlive(this); }