Удобный способ вызова GC::KeepAlive в сценариях C++/CLI?

Я пишу некоторые управляемые оболочки, используя C++/CLI. Проблема в том, что сборщик мусора иногда удаляет объект, пока я использую из него неуправляемые члены. (Я считаю такое поведение безумием, но это уже другая тема). Подробнее см.:

Finalizer запущен, пока его объект все еще используется 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 в dtor, но это повлечет за собой вызов ctor и dtor в каждом методе, что кажется немного чрезмерным.

Есть ли доступная магия С++, которая позволила бы мне избежать переменной temp?

Редактировать

Я понял, что попытка + наконец поможет мне, то есть:

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

В конце концов, я реализовал макрос для обработки этого:

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

person Andreas    schedule 30.04.2009    source источник
comment
Я не думаю, что вы можете сделать защиту, потому что для этого вам нужно будет держать управляемую ссылку в неуправляемом классе - если вы можете, вы можете встроить ctor и dtor так, чтобы это был просто вызов KeepAlive ( но, как я уже сказал, я не думаю, что это возможно)   -  person Lou Franco    schedule 06.05.2009
comment
Я только что столкнулся с тем же: СПАСИБО! Я бегал по кругу, пытаясь найти, где я вызвал повреждение кучи, и все это из-за того, что финализатор освобождает память, пока объект все еще используется... DOH...   -  person Eamon Nerbonne    schedule 20.04.2011


Ответы (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());
}
person Lou Franco    schedule 06.05.2009