Re[6]: Exception from dll -> dll unload -> AV
От: ndemia Россия http://ndemia.com
Дата: 05.12.11 15:09
Оценка:
Выгружать DLL из блока catch при throw из DLL нельзя. Просто нельзя, потому что это неправильно. Даже если кто-то придумает какой-нибудь хитрый ход, который сработает на конкретной версии конкретного компилятора — всё равно нельзя. Потому что в другой версии это не сработает.

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

Здравствуйте, Amor, Вы писали:

A>Здравствуйте, MasterZiv, Вы писали:


MZ>>Если он получает через ссылку на std::exception объект-наследник типа

MZ>>конкретного эксепшена, который реализован в этом компоненте, то этот
MZ>>код также является клиентом этого конкретного эксепшена и этого компонента.
MZ>>В С++ так. Может в других языках было бы по-другому.

A>Код

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

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

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


A>если ты думаешь иначе, то наверно мы не договоримся и тебе лучше уйти.


Про ООП думайте как хотите. FreeLibrary — это не ООП. Это "внезапно грохнуть кусок кода, даже если он сейчас выполняется". И вообще загрузка-выгрузка DLL — это не проблема ни C++, ни ООП вообще. Приложение берётся динамически реогранизовывать своё адресное пространство по ходу своей жизни. Естественно, это нужно делать с оглядкой на эту самую жизнь.

MZ>>Какому-то менеджеру компонент, который в нужный момент, потом, выгрузит

MZ>>указанный компонент.

A>А кто должен его отправлять?


Его должен отправлять тот код, который принимает на себя ответственность убить DLL, но выдаёт предписание другому коду сделать это в другое время.
Это может быть не обязательно сообщение. Можно, например, в список какой-нибудь занести. Чтобы потом, когда гарантированно закончатся все обработки, связанные с этой DLL, можно было бы её грохнуть.


MZ>>В модуле, где реализован этот класс, отку да он экспортируется

MZ>>. тебе какая разница ?

A>Ну это тогда хорошо, потому что выгрузка component.dll будет происходить из my_exception.dll и все это время таблица виртуальных функций класса my_exception будет жива.

A>Только при условии, что my_exception сам лочит component.dll.


MZ>>Почему ? Чё за дурость ? Вечно все почему-то как-то связывают .dll с

MZ>>невозможностью что-то исползовать. DLL-и ничего использовать не мешают.

DLLs ничему не мешают. Просто они динамические (а многие про них думают, как про обычные (т.е. статические) библиотеки. Ну, типа, велосипед — очень неустойчивая конструкция по сравнению с табуреткой).


A>Не мешают конечно, если писать корявый код.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.