Re[7]: Exception from dll -> dll unload -> AV
От: Amor Россия  
Дата: 05.12.11 16:06
Оценка:
Здравствуйте, ndemia, Вы писали:

N>Выгружать DLL из блока catch при throw из DLL нельзя. Просто нельзя, потому что это неправильно. Даже если кто-то придумает какой-нибудь хитрый ход, который сработает на конкретной версии конкретного компилятора — всё равно нельзя. Потому что в другой версии это не сработает.


N>Дело не только во времени жизни вброшенного объекта exception.

N>Пока мы не вышли из последнего ("неперевбрасывающего") блока catch, обработка throw не завершена. И код DLL в этой обработке участвует (по крайней мере, имеет право участвовать — как вбрасывающая функция).

Поэтому я и думаю, можно ли найти грамотное решение с точки зрения С++ и ООП, чтобы о времени жизни объекта/библиотеки думали только клиенты этого объекта/библиотеки.

A>>Код

A>>
A>>catch( std::exception& e )
A>>{
A>>}
A>>

A>>не является клиентом my_exception. Это так в любом ООП-языке.

N>Если my_exception порождён из std::exception, то с чего бы нет? В данном случае "std::exception" — это форма обращения, "внешний вид" того, что по своему происхождению есть "my_exception". И если они прилинкованы из двух разных DLL, то и виртуальные методы одного my_exception могут быть реализованы в разных dll (в зависимости от деклараций).



main()
{
   try
   {
      RunProgram();
   }
   catch( std::exception& e )
   {
      std::cout << "Exception occured: " << e.what() << std::endl;
   }
}


Я говорю, что этот код понятия не имеет о том, кто какой компонент там грузит, и далее — какие библиотеки грузит компонент, которого загрузили, и т.д. и т.п.
А ты, так понимаю предлагаешь примерно следующее

main()
{
   ScopedLoadLibrary lib1( "component1.dll" );
   ScopedLoadLibrary lib2( "component2.dll" );
   ScopedLoadLibrary lib3( "component3.dll" );
   try
   {
      RunProgram();
   }
   catch( std::exception& e )
   {
      std::cout << "Exception occured: " << e.what() << std::endl;
   }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.