Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Case DLL_PROCESS_DETACH: // отключение DLL



break;

}

return TRUE;

}

extern "C" __declspec(dllexport) int count = 5;

extern "C" __declspec(dllexport) int Add(int n)

{

count += n;

return count;

}

extern "C" __declspec(dllexport) int Sub(int n)

{

count -= n;

return count;

}

Динамическая загрузка и отключение DLL

Для динамической загрузки DLL в виртуальную память процесса используются Две функции LoadLibrary и LoadLibraryEx. Функция LoadLibraryEx отличается от функции LoadLibrary только тем, что позволяет управлять режимом загрузки библиотеки. Рассмотрим эти функции подробнее.

Для загрузки динамически подключаемой библиотеки используется функция LoadLibrary, которая имеет следующий прототип:

HMODULE LoadLibrary(

LPCTSTR lpFileName // имя файла

);

В случае успешного завершения эта функция возвращает дескриптор загруженного модуля, а в случае неудачи — null.

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

1. Просматривается каталог, из которого запущено приложение.

2. Просматривается текущий каталог процесса.

3. Просматривается системный каталог Windows.

4. Просматривается каталог Windows.

5. Просматриваются каталоги, которые указаны в переменной окружения PATH.

При этом следует учитывать, что если тип файла не указан, то система по умолчанию считает, что этот файл имеет расширение dll. Для того чтобы отметить, что файл не имеет типа, нужно после имени файла просто указать точку. Если поиск DLL завершился успехом, то библиотека загружается в виртуальную память процесса, а затем вызывается ее функция DllMain с параметром fdwReason, равным значению DLL_PROCESS_ATTACH. Если эта функция возвращает значение false, то она опять вызывается системой, но со значением параметра fdwReason равным DLL_PROCESS_DETACH. После этого DLL выгружается. Для загрузки динамически подключаемых библиотек, а также исполняемых модулей используется функция LoadLibraryEx, которая имеет следующий прототип:

HMODULE LoadLibraryEx(

LPCTSTR lpFileName, // имя файла

HANDLE hFile, // зарезервировано

DWORD dwFlags // флаги управления загрузкой

);

В случае успешного завершения возвращает дескриптор загруженного модуля, а в случае неудачи — null.

Как и в случае с функцией LoadLibrary, параметр lpFiieName должен содержать указатель на имя файла. Поиск загружаемого модуля выполняется по тому же алгоритму, что и функции LoadLibrary, при условии, что в параметре dwFiags не задан флаг, указывающий на альтернативный алгоритм поиска загружаемого модуля. Параметр hFile зарезервирован для дальнейшего использования системой и должен быть всегда установлен в null.

Параметр dwFiags задает флаги управления загрузкой модуля и может принимать одно из следующих значений:

- DONT_RESOLVE_DLL_REFERENCES — в операционных системах Windows NT/2000 после загрузки DLL не вызывается функция DllMain, а также не загружаются дополнительные модули, которые требуются для выполнения этой DLL;

- LOAD_LIBRARY_AS_DATAFILE — в этом случае модуль загружается как файл данных, при этом не выполняются никакие действия по настройке и вызову программ. Отметим, что, в этом случае операционная система Windows 98 разрешает использовать возвращаемый дескриптор модуля только в функциях управления ресурсами;

- LOAD_WITH_ALTERED_SEARCH_PATH — в этом случае при поиске загружаемого модуля в алгоритме поиска не просматривается каталог, из которого запущено приложение. Для отключения DLL от процесса используется функция FreeLibrary, которая имеет следующий прототип:

BOOL FreeLibrary(

HMODULE hModule // дескриптор DLL

);

В случае успешного завершения функция возвращает ненулевое значение, а в случае неудачи — значение false.

В единственном параметре hModule этой функции должен быть установлен дескриптор выгружаемого модуля, который был предварительно получен ФУНКЦИЯМИ LoadLibrary или LoadLibraryEx. Перед выгрузкой DLL из адресного пространства процесса операционная система вызовет функцию DllMain с параметром fdwReason равным значению DLL_PROCESS_ATTACH. Для одновременного завершения потока и отключения DLL используется ФУНКЦИЯ FreeLibraryAndExitThread, которая имеет следующий прототип:

VOID FreeLibraryAndExitThread(

HMODULE hModule, // дескриптор DLL

DWORD dwExitCode // код возврата для потока

Эта функция эквивалентна последовательному вызову следующих двух функций:

FreeLibrary(hModule);

ExitThread(dwExitCode);

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

Использование DLL

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

FARPROC GetProcAddress(

HMODULE hModule, // дескриптор DLL

LPCSTR lpProcName // имя функции

);

В случае успешного завершения возвращает адрес экспортируемой из библиотеки функции, а в случае неудачи null.

Теперь опишем параметры этой функции. Параметр hModule должен содержать дескриптор DLL, который был предварительно получен функцией LoadLibrary или LoadLibraryEx. Параметр lpProcName должен указывать на имя импортируемой функции или ее порядковый номер. В последнем случае для задания порядкового номера функции лучше всего использовать макрос MAKEINTRESOURCE(n), где n задает порядковый номер функции.

Отметим, что функция GetProcAddress может также использоваться и для доступа к экспортируемым переменным из DLL.

#include <windows.h>

#include <iostream>

using namespace std;

int main()

{





Дата публикования: 2015-10-09; Прочитано: 352 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.015 с)...