динамическое связывание Run-Time
Когда приложение вызывает функции LoadLibrary или LoadLibraryEx, система пытается найти библиотеку DLL (дополнительные сведения см. в Dynamic-Link порядке поиска библиотеки). Если поиск выполнен успешно, система сопоставляет модуль DLL в виртуальное адресное пространство процесса и увеличивает число ссылок. Если вызов LoadLibrary или LoadLibraryEx указывает библиотеку DLL, код которой уже сопоставлен с виртуальным адресным пространством вызывающего процесса, функция просто возвращает дескриптор библиотеке DLL и увеличивает число ссылок dll. Обратите внимание, что два библиотеки DLL с одинаковым базовым именем и расширением, но находятся в разных каталогах, не считаются одинаковыми библиотеками DLL.
Система вызывает функцию точки входа в контексте потока, вызываемого LoadLibrary или LoadLibraryEx. Функция точки входа не вызывается, если библиотека DLL уже загружена процессом через вызов LoadLibrary или LoadLibraryEx без соответствующего вызова функции FreeLibrary.
Если система не может найти библиотеку DLL или если функция точки входа возвращает значение FALSE, LoadLibrary или LoadLibraryEx возвращает значение NULL. Если LoadLibrary или LoadLibraryEx успешно, он возвращает дескриптор в модуль DLL. Этот дескриптор может использовать этот дескриптор для идентификации библиотеки DLL в вызове функции GetProcAddress, FreeLibraryили функции FreeLibraryAndExitThread.
Функция GetModuleHandle возвращает дескриптор, используемый в GetProcAddress, FreeLibraryили FreeLibraryAndExitThread. Функция GetModuleHandle завершается успешно, только если модуль DLL уже сопоставлен с адресным пространством процесса путем связывания во время загрузки или предыдущим вызовом LoadLibrary или LoadLibraryEx. В отличие от LoadLibrary или LoadLibraryEx, GetModuleHandle не увеличивает число ссылок на модуль. Функция getModuleFileNameизвлекает полный путь модуля, связанного с дескриптором, возвращаемым GetModuleHandle, LoadLibraryили LoadLibraryEx.
Процесс может использовать GetProcAddress для получения адреса экспортируемой функции в библиотеке DLL с помощью дескриптора модуля DLL, возвращаемого LoadLibrary или LoadLibraryEx, GetModuleHandle.
Если модуль DLL больше не нужен, процесс может вызывать FreeLibrary или FreeLibraryAndExitThread. Эти функции уменьшают количество ссылок на модуль и распакуйте код DLL из виртуального адресного пространства процесса, если число ссылок равно нулю.
Динамическое связывание во время выполнения позволяет процессу продолжать работать, даже если библиотека DLL недоступна. Затем процесс может использовать альтернативный метод для достижения своей цели. Например, если процесс не удается найти одну библиотеку DLL, он может попытаться использовать другой или уведомить пользователя об ошибке. Если пользователь может предоставить полный путь к отсутствующему библиотеке DLL, процесс может использовать эти сведения для загрузки библиотеки DLL, даже если он не находится в обычном пути поиска. Эта ситуация контрастирует с связыванием во время загрузки, в котором система просто завершает процесс, если он не может найти библиотеку DLL.
Динамическое связывание во время выполнения может вызвать проблемы, если библиотека DLL использует функцию DllMain для выполнения инициализации для каждого потока процесса, так как точка входа не вызывается для потоков, которые существовали до LoadLibrary или LoadLibraryEx. Пример, показывающий, как справиться с этой проблемой, см. использование локального хранилища потоков в библиотеке Dynamic-Link.
Связанные разделы