Здравствуйте, 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;
}
}