Удаление статических объектов в dll
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Rycharg Система - это операционная ситема, ОС сокращённо.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#define while if
Оптимизация по размеру:
#define struct union
Romeo, к счастью, моя задача решается просто. В оригинале, статика в своём деструкторе аккуратненько удаляет динамику, которая в своём деструкторе освобождает библиотеку, в которой тоже есть статика, выгружающая динамику, которая из своего деструктора пытается обратиться к первой динамике, в доме, который построил Джек
. Теперь же, имеется метод Clean, вызываемый перед FreeLibrary.
Но мне остаётся непонятно, почему
FreeLibrary себя так ведёт.
AirHend, правда? А я то думал, система – это аппарат президента со всеми диагоналями власти. А если серьёзно, не знаю как Вы, а я представляю себе систему, как программу. С программами можно “говорить” лишь рассылая сообщения. Но это асинхронность и это противоречит Вашим утверждениям, на что и указал Romeo. Вот я и спросил, что Вы понимаете под системой.


FreeLibrary себя так ведёт.
AirHend, правда? А я то думал, система – это аппарат президента со всеми диагоналями власти. А если серьёзно, не знаю как Вы, а я представляю себе систему, как программу. С программами можно “говорить” лишь рассылая сообщения. Но это асинхронность и это противоречит Вашим утверждениям, на что и указал Romeo. Вот я и спросил, что Вы понимаете под системой.
На этом форуме подобные темы уже обсуждались. Вот к примеру мной созданная тема: http://forum.developing.ru/showthread.p ... #post66141
Прочитай сообщение под номером 18, там как раз я описал собственный эксперимент с загрузкой и выгрузкой DLL.
Прочитай сообщение под номером 18, там как раз я описал собственный эксперимент с загрузкой и выгрузкой DLL.
Поумнеть несложно, куда труднее от дури избавиться.
Вообще-то сама по себе идеология конвейерной загрузки динамических библиотек (т.е. когда один модуль явным образом загружает другой, а тот загружает третий) весьма сомнительная с точки зрения надёжности такого решения. Понятно, что большинство динамических библиотек всё равно загружают другие динамические модули, как например системные библиотеки Windows. Но там и механизм связывания совсем другой. В этом случае связывание происходит на стадии сборки проекта, с помощью так называемых библиотек импорта, и эта связь практически никак не зависит от программного кода самой DLL. Т.е. процесс загрузки/выгрузки модулей контролируется самой операционной системой.
В твоём случае можно пойти по двум направлениям:
1. Межмодульную связь реализовать через библиотеки импорта (LIB-файлы) и обойтись без явной загрузки DLL.
2. Изменить архитектуру проекта таким образом, чтобы процесс загрузки/выгрузки динамических библиотек выполнялся и контролировался основным приложением (ЕХЕ-файлом), а не другими DLL-модулями.
В твоём случае можно пойти по двум направлениям:
1. Межмодульную связь реализовать через библиотеки импорта (LIB-файлы) и обойтись без явной загрузки DLL.
2. Изменить архитектуру проекта таким образом, чтобы процесс загрузки/выгрузки динамических библиотек выполнялся и контролировался основным приложением (ЕХЕ-файлом), а не другими DLL-модулями.
WinMain, спасибо. Такое простое решение мне в голову не приходило. Недостаток опыта - вещь печальная, но поправимая. ( Статическая компановка не подходит, т.к. имеет место конвейерная выгрузка, а не загрузка. )2. Изменить архитектуру проекта таким образом, чтобы процесс загрузки/выгрузки динамических библиотек выполнялся и контролировался основным приложением (ЕХЕ-файлом), а не другими DLL-модулями.
Decoder, сообщение №18 не открыло мне ничего нового. Как и ты, придерживаюсь мнения, что библиотека выгружена, если на месте глобальных объектов находится мусор. ( Кстати, мусором их делает "проход" по деструкторам, которого я и не наблюдал в своём примере во время "внутреннего" вызова FreeLibrary. Airhand предлагал подождать, мол, система через пол часика всё уничтожит. Но он ошибался. Через деструкторы проходит не система, а поток приложения, вызвавший FreeLibrary. )
Всем спасибо, вопрос снимаю. Считаю явление, которое мне довелось пронаблюдать, необъяснимым чудом OS Windows.
вставлю свои пять копеек, вопрос с выгрузкой библиотек заинтересовал потому что моё приложение, использующее чужие библиотеки, валится при выгрузке одной из них, конешно не совсем в тему но на цитфоруме написано:
Когда загруженная динамическая библиотека больше не нужна - ее можно освободить, вызвав функцию BOOL FreeLibrary(HMODULE hLibModule) и передав ей дескриптор библиотеки, ранее возвращенный функцией LoadLibrary. Обратите внимание - DLL можно именно освободить, но не выгрузить! Выгрузка DLL из памяти не гарантируется, даже если работу с ней завершили все ранее загрузившие ее процессы.
Задержка выгрузки предусмотрена специально - на тот случай, если эта же DLL через некоторое время вновь понадобится какому-то процессу. Такой трюк оптимизирует работу часто используемых динамических библиотек, но плохо подходит для редко используемых DLL, загружаемых лишь однажды на короткое время. Никаких документированных способов насильно выгрузить динамическую библиотеку из памяти нет; а те, что есть - работают с ядром на низком уровне и не могут похвастаться переносимостью. Поэтому здесь мы их рассматривать не будем. К тому же - тактика освобождения и выгрузки DLL по-разному реализована в каждой версии Windows: Microsoft, стремясь подобрать наилучшую стратегию, непрерывно изменяет этот алгоритм; а потому и отказывается его документировать.
Нельзя не обратить внимания на одно очень важное обстоятельство: динамическая библиотека не владеет никакими ресурсами - ими владеет, независимо от способа компоновки, загрузивший ее процесс. Динамическая библиотека может открывать файлы, выделять память и т. д., но память не будет автоматически освобождена после вызова FreeLibrary, а файлы не окажутся сами собой закрыты - все это произойдет лишь после завершения процесса, но не раньше! Естественно, если программист сам не освободит все ненужные ресурсы вручную, с помощью функций CloseHandle, FreeMemory и подобных им.
Если функция FreeLibrary пропущена, DLL освобождается (но не факт, что выгружается!) только после завершения вызвавшего процесса. Могут возникнуть сомнения: раз FreeLibrary немедленно не выгружает динамическую библиотеку из памяти, так зачем она вообще нужна? Не лучше ли тогда все пустить на самотек - все равно ведь загруженные DLL будут гарантированно освобождены после завершения процесса? Что ж, доля правды тут есть, и автор сам порой так и поступает; но при недостатке памяти операционная система может беспрепятственно использовать место, занятое освобожденными динамическими библиотеками под что-то полезное - а если DLL еще не освобождены, их придется "скидывать" в файл подкачки, теряя драгоценное время. Поэтому лучше освобождайте DLL сразу же после их использования!
Когда загруженная динамическая библиотека больше не нужна - ее можно освободить, вызвав функцию BOOL FreeLibrary(HMODULE hLibModule) и передав ей дескриптор библиотеки, ранее возвращенный функцией LoadLibrary. Обратите внимание - DLL можно именно освободить, но не выгрузить! Выгрузка DLL из памяти не гарантируется, даже если работу с ней завершили все ранее загрузившие ее процессы.
Задержка выгрузки предусмотрена специально - на тот случай, если эта же DLL через некоторое время вновь понадобится какому-то процессу. Такой трюк оптимизирует работу часто используемых динамических библиотек, но плохо подходит для редко используемых DLL, загружаемых лишь однажды на короткое время. Никаких документированных способов насильно выгрузить динамическую библиотеку из памяти нет; а те, что есть - работают с ядром на низком уровне и не могут похвастаться переносимостью. Поэтому здесь мы их рассматривать не будем. К тому же - тактика освобождения и выгрузки DLL по-разному реализована в каждой версии Windows: Microsoft, стремясь подобрать наилучшую стратегию, непрерывно изменяет этот алгоритм; а потому и отказывается его документировать.
Нельзя не обратить внимания на одно очень важное обстоятельство: динамическая библиотека не владеет никакими ресурсами - ими владеет, независимо от способа компоновки, загрузивший ее процесс. Динамическая библиотека может открывать файлы, выделять память и т. д., но память не будет автоматически освобождена после вызова FreeLibrary, а файлы не окажутся сами собой закрыты - все это произойдет лишь после завершения процесса, но не раньше! Естественно, если программист сам не освободит все ненужные ресурсы вручную, с помощью функций CloseHandle, FreeMemory и подобных им.
Если функция FreeLibrary пропущена, DLL освобождается (но не факт, что выгружается!) только после завершения вызвавшего процесса. Могут возникнуть сомнения: раз FreeLibrary немедленно не выгружает динамическую библиотеку из памяти, так зачем она вообще нужна? Не лучше ли тогда все пустить на самотек - все равно ведь загруженные DLL будут гарантированно освобождены после завершения процесса? Что ж, доля правды тут есть, и автор сам порой так и поступает; но при недостатке памяти операционная система может беспрепятственно использовать место, занятое освобожденными динамическими библиотеками под что-то полезное - а если DLL еще не освобождены, их придется "скидывать" в файл подкачки, теряя драгоценное время. Поэтому лучше освобождайте DLL сразу же после их использования!