Главная » Win32 API » Функция входа/выхода DLL

0

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

Особое значение имеет деинициализация: поскольку при отключе­нии DLL от адресного пространства процесса вьщеленная ею память сама собой не освобождается, а открытые файлы не закрываются, DLL должна самостоятельно обеспечивать «уборку мусора».

Для решения указанных проблем вы можете включить в состав DLL специальную функцию точки входа DllMain. Эта функция вызы­вается операционной системой в следующих случаях:

когда DLL проецируется на адресное пространство процесса (подключение DLL);

-  когда процессом, загрузившим DLL, вызывается новый поток;

-  когда завершается поток, принадлежащий процессу, который свя­зан с DLL;

-когда процесс освобождает DLL (отключение DLL). Функция точки входа DllMain имеет следующий прототип:

BOOL WINAPI DllMain(

HINSTANCE hinstDLL, // дескриптор DLL-модуля DWORD fdwreason, // флаг причины вызова функции LPVOID lpvReserved // дополнительная информация

)   ;

В момент вызова функция получает информацию от операционной системы через свои параметры.

Первый параметр, hinstDLL, принимает значение дескриптора мо­дуля DLL, являющееся, по сути, виртуальным адресом загрузки DLL. Если в библиотеке имеются вызовы функций, которым нужен данный дескриптор, необходимо сохранить значение hinstDLL в глобальной переменной.

Второй параметр, fdwReason, может принимать одно из следующих значений:

-  DLLPROCESSATTACH уведомление о том, что DLL загруже­на в адресное пространство процесса либо в результате его старта, ли­бо в результате вызова функции LoadLibrary;

-  DLLTHREADATTACH уведомление о том, что текущий про­цесс создал новый поток. Это уведомление посылается всем DLL, под­ключенным к процессу. Вызов DllMain происходит в контексте нового потока;

-  DLLTHREADDETACH уведомление о том, что поток кор­ректно завершается. Вызов DllMain происходит в контексте завер­шающегося потока;

DLLPROCESSDETACH уведомление о том, что DLL отключа­ется от адресного пространства процесса в результате одного из трех событий: а) неудачное завершение загрузки DLL; б) вызов функции FreeLibrary; в) завершение процесса.

Если при вызове функции используется первый параметр со значе­нием DLLPROCESSATTACH, то по значению третьего параметра можно выяснить, каким способом загружается DLL. При явной загрузке параметр IvlReserved равен нулю, а при неявной загрузке принимает ненулевое значение.

Следует отметить следующие моменты работы с функцией входа-выхода DLL:

1.                    Поток,         вызвавший         DllMain         со         значением DLLPROCESSATTACH, не вызывает повторно DllMain со значени­ем DLLTHREADATTACH.

2.                    Когда DLL загружается вызовом функции LoadLibrary, суще­ствующие потоки не вызывают DllMain для вновь загруженной биб­лиотеки.

3.                    Функция DllMain не вызывается, если поток или процесс за­вершаются по причине вызова функции TerminateThread или TerminateProcess.

Поскольку функция DllMain должна обрабатывать все возможные причины своего вызова, то в ее коде обьгано анализируется dwReason и выполняются необходимые действия по инициализации или освобо­ждению ресурсов.

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии