Динамическая загрузка и отключение DLL
Для динамической загрузки DLL в виртуальную память процесса используются две функции LoadLibrary и LoadLibraryEx. Функция LoadLibraryEx отличается от функции LoadLibrary только тем, что позволяет управлять режимом загрузки библиотеки. Рассмотрим эти функции подробнее.
Для загрузки динамически подключаемой библиотеки используется функция LoadLibrary, которая имеет следующий прототип:
HMODULE LoadLibrary(
LPCTSTR lpFileName // имя файла
);
В случае успешного завершения эта функция возвращает дескриптор загруженного модуля, а в случае неудачи — null.
Единственный параметр этой функции указывает на строку, содержащую имя загружаемого файла. Если эта строка содержит полный путь к файлу, то именно этот файл и загружается. Если же указано только имя файла, то сначала система определяет, не был ли загружен этот модуль ранее. Если да, то система возвращает дескриптор уже загруженного модуля, в противном случае — для загрузки используется следующий алгоритм поиска.
1. Просматривается каталог, из которого запущено приложение.
2. Просматривается текущий каталог процесса.
3. Просматривается системный каталог Windows.
4. Просматривается каталог Windows.
5. Просматриваются каталоги, которые указаны в переменной окружения PATH.
При этом следует учитывать, что если тип файла не указан, то система по умолчанию считает, что этот файл имеет расширение dll. Для того чтобы отметить, что файл не имеет типа, нужно после имени файла просто указать точку.
Если поиск DLL завершился успехом, то библиотека загружается в виртуальную память процесса, а затем вызывается ее функция DiiMain с параметром fdwReason, равным значению dll_process_attach. Если эта функция возвращает значение false, to она опять вызывается системой, но со значением параметра 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 не вызывается функция DiiMain, а также не загружаются дополнительные модули, которые требуются для выполнения этой DLL;
□ load_library_as_datafile — в этом случае модуль загружается как файл данных, при этом не выполняются никакие действия по настройке и вызову программ. Отметим, что, в этом случае операционная система Windows 98 разрешает использовать возвращаемый дескриптор модуля только в функциях управления ресурсами;
□ load_with_altered_search_path — в этом случае при поиске загружаемого модуля в алгоритме поиска не просматривается каталог, из которого запущено приложение.
Для отключения DLL от процесса используется функция FreeLibrary, которая имеет следующий прототип:
BOOL FreeLibrary(
HMODULE hModule // дескриптор DLL
);
В случае успешного завершения функция возвращает ненулевое значение, а в случае неудачи — значение false.
В единственном параметре hModule этой функции должен быть установлен дескриптор выгружаемого модуля, который был предварительно получен функциями LoadLibrary или LoadLibraryEx.
Перед выгрузкой DLL из адресного пространства процесса операционная система вызовет функцию DiiMain с параметром fdwReason равным значению DLL_PROCESS_ATTACH.
Для одновременного завершения потока и отключения DLL используется функция FreeLibraryAndExitThread, которая имеет следующий прототип:
VOID FreeLibraryAndExitThread(
HMODULE hModule, // дескриптор DLL
DWORD dwExitCode // код возврата для потока
Эта функция эквивалентна последовательному вызову следующих двух функций:
FreeLibrary(hModule);
ExitThread(dwExi tCode);
Вызов этой функции имеет смысл только в потоке динамической библиотеки, который одновременно завершает свою работу и выгружает саму эту библиотеку.
Использование DLL
Если программа использует некоторые функции и переменные из DLL, то говорят, что она импортирует их из DLL. Для обеспечения доступа к импортируемым из DLL функциям и переменным используется функция GetProcAddress, которая имеет следующий прототип:
FARPROC GetProcAddress(
HMODULE hModule, // дескриптор DLL
LPCSTR lpProcName // имя функции
);
В случае успешного завершения возвращает адрес экспортируемой из библиотеки функции, а в случае неудачи null. Теперь опишем параметры этой функции.
Параметр hModule должен содержать дескриптор DLL, который был предварительно получен функцией LoadLibrary или LoadLibraryEx.
Параметр lpProcName должен указывать на имя импортируемой функции или ее порядковый номер. В последнем случае для задания порядкового номера функции лучше всего использовать макрос MAKEiNTRESOURCE(n), где n задает порядковый номер функции.
ПЛАНЫ СЕМИНАРСКИХ, ПРАКТИЧЕСКИХ, ЛАБОРАТОРНЫХ И СТУДИЙНЫХ ЗАНЯТИЙ
№ недели | Название семинарских, практических, лабораторных и студийных занятий | Объем в часах |
Работа с символьными строками | ||
Представление в памяти массивов и матриц | ||
Структуры и связные списки | ||
Проверка состава оборудования | ||
Управление клавиатурой | ||
Управление таймером | ||
7-8 | Управление видеоадаптером | |
Главная Загрузочная Запись | ||
Дисковые структуры данных DOS | ||
Управление программами | ||
Драйверы DOS | ||
Распределение памяти | ||
14-15 | Управление памятью | |
Всего: |