Здавалка
Главная | Обратная связь

Динамическое подключение DLL



Чтобы поток мог вызвать функцию из DLL-модуля, последний нужно спроецировать на адресное пространство процесса, которому принадлежит этот поток. Сделать это можно двумя способами. Первый состоит в том, что при разработке приложения декларативно объявляется, какие DLL будут использованы. Это заставляет загрузчик загружать (и связывать) нужные DLL при запуске приложения.

Другой способ – динамическая загрузка и связывание требуемой DLL во время выполнения приложения. Особенность данного подхода в том, что загрузка DLL может выполняться отложено.

В любой момент поток может спроецировать DLL на адресное пространство процесса, вызвав одну из функций:

HINSTANCE LoadLibrary(PCSTR dllFileName);

HINSTANCE LoadLibraryEx(PCSTR dllFileName, HANDLE hFile, DWORD flags);

Обе функции производят поиск DLL-файла dllFileName и пытаются спроецировать его на адресное пространство вызывающего процесса. Возвращаемое значение типа HINSTANCE сообщает адрес виртуальной памяти, по которому спроецирован образ файла.

Если имя DLL-файла dllFileName указано не полностью, поиск DLL осуществляется в следующей последовательности:

1. Каталог, содержащий exe-файл вызывающего процесса.

2. Текущий каталог вызывающего процесса.

3. Системный каталог Windows.

4. Основной каталог Windows.

5. Каталоги, перечисленные в переменной окружения Path.

Параметр hFile функции LoadLibraryEx зарезервирован для использования в будущих версиях и должен быть равен NULL. Параметр flags определяет режим работы функции, то есть то, как именно должна быть загружена указанная DLL.

Если необходимость в DLL отпадает, ее можно выгрузить из адресного пространства процесса, вызвав функцию FreeLibrary:

BOOL FreeLibrary(HINSTANCE hModule);

Параметр hModule идентифицирует выгружаемую DLL.

Для получения адреса экспортируемого идентификатора из динамически загруженной DLL, необходимо вызвать функцию GetProcAddress:

FARPROC GetProcAddress(HMODULE hModule, PCSTR procName);

Параметр hModule идентифицирует DLL-модуль, в котором производится поиск функции с именем procName. Результатом работы GetProcAddress служит адрес содержащегося в DLL идентификатора. Если идентификатор не найден, возвращается NULL.

Ниже приведен код, в котором производится динамическая загрузка DLL-модуля, после чего осуществляется поиск и вызов определенной в нем функции:

// Описание прототипа импортируемой функции

typedef void (*ShowDialogFunction)(char[], char[]);

 

...

 

// Загрузка DLL

HINSTANCE hModule = LoadLibrary("SomeDll.dll");

 

if (hModule != NULL)

{

// Поиск адреса функции

ShowDialogFunction ShowDialog =

(ShowDialogFunction)GetProcAddress(hModule, "ShowDialog");

 

if (ShowDialog != NULL)

{

ShowDialog("Text", "Caption");

}

 

// Выгрузка DLL

FreeLibrary(hModule);

}

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








©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.