我正在使用C ++ / CLI编写一些托管包装器。问题是当我使用非托管成员时,GC有时会处理对象。 (我认为这种行为是疯狂的,但这是另一个话题)。有关详细信息,请参阅:
Finalizer launched while its object was still being used 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;
}
这对我来说有点难看。
我考虑过在守护进程中调用GC :: KeepAlive的守护类,但这会导致每个看起来有点过分的方法都会调用ctor和dtor。
是否有可用的C ++魔法可以让我避开临时变量?
我意识到尝试+最终会为我做的伎俩,即:
int ComputeInt() {
try {
return m_unmanagedMember->LongRunningComputation();
} finally {
GC::KeepAlive(this);
}
}
最后,我实现了一个宏来处理这个问题:
#define KEEPALIVE_RETURN(x) try {\
return x;\
} finally { System::GC::KeepAlive(this); }
答案 0 :(得分: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());
}