Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Библиотека DLL может дополнительно указать функцию точки входа. При наличии система вызывает функцию точки входа всякий раз, когда процесс или поток загружает или выгружает библиотеку DLL. Его можно использовать для выполнения простых задач инициализации и очистки. Например, он может настроить локальное хранилище потока при создании нового потока и очистить его при завершении потока.
Если вы связываете библиотеку dll с библиотекой времени выполнения C, она может предоставить функцию точки входа и предоставить отдельную функцию инициализации. Дополнительные сведения см. в документации по библиотеке времени выполнения.
Если вы предоставляете собственную точку входа, см. функцию DllMain. Имя DllMain является заполнителем для определяемой пользователем функции. Необходимо указать фактическое имя, используемое при сборке библиотеки DLL. Дополнительные сведения см. в документации, включенной в средства разработки.
Вызов функции Entry-Point
Система вызывает функцию точки входа всякий раз, когда происходит одно из следующих событий:
- Процесс загружает библиотеку DLL. Для процессов с использованием динамической компоновки во время загрузки библиотека DLL загружается во время инициализации процесса. Для процессов, использующих связывание во время выполнения, библиотека DLL загружается перед возвратом LoadLibrary или LoadLibraryEx.
- Процесс выгрузит библиотеку DLL. Библиотека DLL выгружается при завершении процесса или вызове функции FreeLibrary, а число ссылок становится нулевым. Если процесс завершается в результате функции TerminateProcess или TerminateThread, система не вызывает функцию точки входа DLL.
- Новый поток создается в процессе загрузки библиотеки DLL. Функцию DisableThreadLibraryCallsможно использоватьдля отключения уведомлений при создании потоков.
- Поток процесса, загруженного библиотекой DLL, завершается нормально, а не с помощью TerminateThread или TerminateProcess. При выгрузке библиотеки DLL функция точки входа вызывается только один раз для всего процесса, а не один раз для каждого существующего потока процесса. Вы можете использовать DisableThreadLibraryCalls, чтобы отключить уведомление при завершении потоков.
Только один поток за раз может вызывать функцию точки входа.
Система вызывает функцию точки входа в контексте процесса или потока, вызвавшего функцию. Это позволяет библиотеке DLL использовать ее функцию точки входа для выделения памяти в виртуальном адресном пространстве вызывающего процесса или открытия дескрипторов, доступных процессу. Функция точки входа также может выделить память, которая является частной для нового потока с помощью локального хранилища потока (TLS). Дополнительные сведения о локальном хранилище потоков см. в локальном хранилище потока.
Определение функции Entry-Point
Функция точки входа DLL должна быть объявлена с помощью соглашения о вызове стандартного вызова. Если точка входа DLL не объявлена правильно, библиотека DLL не загружается, а система отображает сообщение, указывающее, что точка входа DLL должна быть объявлена с помощью WINAPI.
В тексте функции можно обрабатывать любое сочетание следующих сценариев, в которых была вызвана точка входа DLL:
- Процесс загружает библиотеку DLL (DLL_PROCESS_ATTACH).
- Текущий процесс создает новый поток (DLL_THREAD_ATTACH).
- Поток обычно завершается (DLL_THREAD_DETACH).
- Процесс выгрузит библиотеку DLL (DLL_PROCESS_DETACH).
Функция точки входа должна выполнять только простые задачи инициализации. Он не должен вызывать функцию LoadLibrary или LoadLibraryEx (или функцию, которая вызывает эти функции), так как это может создавать циклы зависимостей в порядке загрузки библиотеки DLL. Это может привести к использованию библиотеки DLL, прежде чем система выполнила свой код инициализации. Аналогичным образом функция точки входа не должна вызывать функцию FreeLibrary (или функцию, которая вызывает FreeLibrary) во время завершения процесса, так как это может привести к использованию библиотеки DLL после выполнения системы кода завершения.
Так как Kernel32.dll гарантированно загружается в адресное пространство процесса при вызове функции точки входа, вызов функций в Kernel32.dll не приводит к использованию библиотеки DLL до выполнения кода инициализации. Поэтому функция точки входа может создавать объекты синхронизации , такие как критические разделы и мьютексы, а также использовать TLS, так как эти функции находятся в Kernel32.dll. Например, небезопасно вызывать функции реестра, так как они находятся в Advapi32.dll.
Вызов других функций может привести к проблемам, которые сложно диагностировать. Например, вызов функций User, Shell и COM может привести к ошибкам нарушения доступа, так как некоторые функции в библиотеках DLL вызывают LoadLibrary для загрузки других системных компонентов. И наоборот, вызов этих функций во время завершения может привести к ошибкам нарушения доступа, так как соответствующий компонент уже был выгружен или неинициализирован.
В следующем примере показано, как структурировать функцию точки входа DLL.
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
возвращаемое значение функции Entry-Point
Если функция точки входа DLL вызывается из-за загрузки процесса, функция возвращает TRUE, чтобы указать успешность. Для процессов, использующих связывание во время загрузки, возвращаемое значение FALSE приводит к сбою и завершения процесса инициализации процесса. Для процессов, использующих связывание во время выполнения, возвращаемое значение FALSE приводит к тому, что функция LoadLibrary или LoadLibraryEx возвращает NULL, указывающую на сбой. (Система немедленно вызывает функцию точки входа с DLL_PROCESS_DETACH и выгрузит библиотеку DLL.) Возвращаемое значение функции точки входа игнорируется при вызове функции по любой другой причине.