Я пишу некоторые управляемые оболочки, используя 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); }