Программирование для Windows NT (том 2)

       

Инициализация 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;

    }


    Содержание раздела