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 + finally 会为我解决问题,即:

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 回答