在C ++ / CLI场景中调用GC :: KeepAlive的便捷方法?

时间:2009-04-30 07:26:23

标签: .net c++ garbage-collection finalizer

我正在使用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); }

1 个答案:

答案 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());
}