3

私は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); }
4

1 に答える 1

2

次のようなものはどうですか(実際には構文をチェックしていません)

template<class RType>
const RType& KeepAliveRet(Object^ o, const RType& ret)
{
    GC::KeepAlive(o);
    return ret;
} 


int ComputeInt() {
   return KeepAliveRet(this, m_unmanagedMember->LongRunningComputation());
}
于 2009-05-06T13:51:40.210 に答える