Инициализация DLL-библиотеки в среде Microsoft Windows NT
В 32-разрядных DLL-библиотеках операционной системы Microsoft Windows NT вместо функций LibMain и WEP используется одна функция DLLEntryPoint, которая выполняет все необходимые задачи по инициализации библиотеки и при необходимости освобождает заказанные ранее ресурсы (имя функции инициализации может быть любым).
Функции LibMain и WEP вызываются только один раз при загрузке библиотеки в память и при ее выгрузке. В отличие от них, функция DLLEntryPoint вызывается всякий раз, когда выполняется инициализация процесса или задачи, обращающихся к функциям библиотеки, а также при явной загрузке и выгрузке библиотеки функциями LoadLibrary и FreeLibrary.
Ниже мы привели прототип функции DLLEntryPoint:
BOOL WINAPI DllEntryPoint(
HINSTANCE hinstDLL, // идентификатор модуля DLL-библиотеки
DWORD fdwReason, // код причины вызова функции
LPVOID lpvReserved); // зарезервировано
Через параметр hinstDLL функции DLLEntryPoint передается идентификатор модуля DLL-библиотеки, который можно использовать при обращении к ресурсам, расположенным в файле этой библиотеки.
Что же касается параметра fdwReason, то он зависит от причины, по которой произошел вызов функции DLLEntryPoint. Этот параметр может принимать следующие значения:
Значение | Описание | ||
DLL_PROCESS_ATTACH | Библиотека отображается в адресное пространство процесса в результате запуска процесса или вызова функции LoadLibrary | ||
DLL_THREAD_ATTACH | Текущий процесс создал новую задачу, после чего система вызывает функции DLLEntryPoint всех DLL-библиотек, подключенных к процессу | ||
DLL_THREAD_DETACH | Этот код причины передается функции DLLEntryPoint, когда задача завершает свою работу нормальным (не аварийным) способом | ||
DLL_PROCESS_DETACH | Отображение DLL?библиотеки в адресное пространство отменяется в результате нормального завершения процесса или вызова функции FreeLibrary |
Параметр lpvReserved зарезервирован. В SDK, тем не менее, сказано, что значение параметра lpvReserved равно NULL во всех случаях, кроме двух следующих:
- когда параметр fdwReason равен DLL_PROCESS_ATTACH и используется статическая загрузка DLL-библиотеки;
- когда параметр fdwReason равен DLL_PROCESS_DETACH и функция DLLEntryPoint вызвана в результате завершения процесса, а не вызова функции FreeLibrary
В процессе инициализации функция DLLEntryPoint может отменить загрузку DLL-библиотеки. Если код причины вызова равен DLL_PROCESS_ATTACH, функция DLLEntryPoint отменяет загрузку библиотеки, возвращая значение FALSE. Если же инициализация выполнена успешно, функция должна возвратить значение TRUE.
В том случае, когда приложение пыталось загрузить DLL-библиотеку функцией LoadLibrary, а функция DLLEntryPoint отменила загрузку, функция LoadLibrary возвратит значение NULL. Если же приложение выполняет инициализацию DLL-библиотеки неявно, при отмене загрузки библиотеки приложение также не будет загружено для выполнения.
Приведем пример функции инициализации DLL-библиотеки:
BOOL WINAPI DLLEntryPoint(
HMODULE hModule, // идентификатор модуля
DWORD fdwReason, // причина вызова функции DLLEntryPoint
LPVOID lpvReserved)// зарезервировано
{
switch(fdwReason)
{
// Подключение нового процесса
case DLL_PROCESS_ATTACH:
{
// Обработка подключения процесса
. . .
break;
}
// Подключение новой задачи
case DLL_THREAD_ATTACH:
{
// Обработка подключения новой задачи
. . .
break;
}
// Отключение процесса
case DLL_PROCESS_DETACH:
{
// Обработка отключения процесса
. . .
break;
}
// Отключение задачи
case DLL_THREAD_DETACH:
{
// Обработка отключения задачи
. . .
break;
}
}
return TRUE;
}