Convenient way to call GC :: KeepAlive in C ++ / CLI scripts?

I write several managed shells using C ++ / CLI. The problem is that GC sometimes deletes an object while I use unmanaged elements from it. (I think this behavior is crazy, but this is another topic). For more details see:

Finalizer is running while its object is still in use http://blogs.msdn.com/cbrumme/archive/2003/04/19/51365.aspx

I am looking for a convenient way to call:

GC::KeepAlive(this);

at the end of each method. For simple old void methods, this is quite simple, but for methods that return values, it is a little more complicated.

int ComputeInt() {
   return m_unmanagedMember->LongRunningComputation();
}

would need to be turned into:

int ComputeInt() {
   int tmp = m_unmanagedMember->LongRunningComputation();
   GC::KeepAlive(this);
   return tmp;
}

It looks a little ugly to me.

I counted the guard class that calls GC :: KeepAlive in dtor, but that would cause a ctor and dtor call in every method, which seems a bit overkill.

++, temp?

, +, , , :

int ComputeInt() {
   try {
      return m_unmanagedMember->LongRunningComputation();
   } finally {
      GC::KeepAlive(this);
   }
}

, :

#define KEEPALIVE_RETURN(x) try {\
    return x;\
} finally { System::GC::KeepAlive(this); }
+3
1

- ( )

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


int ComputeInt() {
   return KeepAliveRet(this, m_unmanagedMember->LongRunningComputation());
}
+2

Source: https://habr.com/ru/post/1707396/


All Articles