powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / спешу делиться опытом
6 сообщений из 6, страница 1 из 1
спешу делиться опытом
    #34747376
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помнится спрашивал я где-то на форуме по поводу корректного освобождения библиотек при загрузке через LoadLibrary и фиксации BoundsChecker'ом (а точнее Error Detection) неосвобожденного ресурса при их освобождении через FreeLibrary, в конце их использования, но мне так никто не ответил отчего это так происходит. Искал, искал, но что-то не нашел, поэтому поднял еще одну тему. Кратко напомню о чем речь. Вот такой абстрактный код

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
int main(...)
{
HMODULE hModule = ::LoadLibrary(____"AnyLibName.dll"___);
.
.
.
if(hModule)
::FreeLibrary(hModule)
}

вызывает ошибку при проверке в BoundsChecker'e. Последний утверждает что библиотека осталась невыгруженной. Причем если ставить брэки, то функция FreeLibrary срабатывает, но результат остается прежним. Что я только не делал и какие попытки не предпринимал, результата так и не добился, BC упорно утверждает что библиотека не освобождена.
Сегодня совершенно случайно я наткнулся на функцию FreeLibraryAndExitThread, которая совершила маленькое чудо, избавив меня от этой проблемы, но все же тень сомнения осталась, насколько корректно будет заменить ею FreeLibrary и на чем это может сказаться?
Получается что загрузив библиотеку мы создаем еще один поток и для того чтобы корректно завершить использование библиотеки недостаточно, как утверждает msdn, просто вызвать FreeLibrary, нужно еще и поток прибить.
Я понимаю что эту "ошибку" вполне разрулит ядро ОС, когда приложение завершится, но все же хотелось понять отчего так...

--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
спешу делиться опытом
    #34747614
Tubrik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RichterЯвная выгрузка DLL
Если необходимость в DLL отпадает, ее можно выгрузить из адресного пространства процесса, вызвав функцию.


Код: plaintext
BOOL FreeLibrary(HINSTANCE hinstDll); 


Вы должны передать в FreeLibrary значение типа HINSTANCE, которое идентифицирует выгружаемую DLL. Это значение Вы получаете после вызова LoadLibrary(Ex).

DLL можно выгрузить и с помощью другой функции:


Код: plaintext
VOID FreeLibraryAndExitThread( HlNSTANCE hinstDll, DWORD dwExitCode); 


Она реализована в Kernel32.dll так:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
VOID FreeLibraryAndExitThread(HINSTANCE hinstDll, DWORD dwExitCode) 
{ 

FreeLibrary(hinstDll); 
ExitThread(dwExitCode); 

} 

На первый взгляд, в ней нет ничего особенного, и Вы, наверное, удивляетесь, с чего это Microsoft решила ее написать. Но представьте такой сценарий. Вы пишете DLL, которая при первом отображении на адресное пространство процесса создает поток. Последний, закончив свою работу, отключает DLL от адресного пространства процесса и завершается, вызывая сначала FreeLibrary, а потом ExttThread.

Если поток станет сам вызывать FreeLibrary и ExitThread, возникнет очень серьезная проблема: FreeI.ibrary тут же отключит DLL от адресного пространства процесса. После возврата из FreeLibrary код, содержащий вызов ExttThread, окажется недоступен, и поток попытается выполнить не известно что. Это приведет к нарушению доступа и завершению всего процесса!

С другой стороны, если поток обратится к FreeLibraryAndExitThread, она вызовет FreeLibrary, и та сразу же отключит DLL, Но следующая исполняемая инструкция находится в KerneI32.dlI, а не в только что отключенной DLL. Значит, поток сможет продолжить выполнение и вызвать ExitThread, которая корректно завершит его, не возвращая управления.
...
Рейтинг: 0 / 0
спешу делиться опытом
    #34747632
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
о да, великий Рихтер знает все, жаль я не он...
--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
спешу делиться опытом
    #34751860
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Tubrik RichterЕсли поток станет сам вызывать FreeLibrary и ExitThread, возникнет очень серьезная проблема:Угу... и при этом в описании DllMain несколько раз говорится: Не надо выгружать самого себя.
...
Рейтинг: 0 / 0
спешу делиться опытом
    #34751885
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а как правильно?
--------------------------------------------------------------
[не претендую на уникальность]
...
Рейтинг: 0 / 0
спешу делиться опытом
    #34751903
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrumа как правильно?Что как правильно?
Как правильно завершать DLL? Документацию открывать не пробовал? Читай тут: http://msdn2.microsoft.com/en-us/library/ms682583.aspx
Да и вообще, вам в школе инкапсуляцию объясняли? DLL это тот же класс. У него имеются свои методы, и свои внутренние объекты. Функция DllMain является конструктором и деструктором этого класса. Объект сам себя не уничтожает, в своем деструкторе он уничтожает свои внутренние объекты/нити, но никогда сам себя.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / спешу делиться опытом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]