logo
ОСиС-2014(Передача№1) / 1_ОперСистСети_ЛР_Методичка_2012 / ОС_ЛР-09-13-14 / LAB7 / LAB7

Подключение dll на этапе выполнения

Такой способ подключения обычно используется в двух случаях:

- когда функции DLL используются только в течение определенного этапа работы программы (например – аутентификация пользователя при запуске);

- когда программе требуются ресурсы из DLL.

Для подключения DLL используются функции:

function LoadLibrary(lpLibFileName: PChar): HMODULE;

function LoadLibraryEx(lpLibFileName: PChar; hFile: THandle; dwFlags: DWORD): HMODULE;

В качестве первого параметра передается указатель на строку с именем файла исполнимого модуля. С помощью этих функций можно загружать как DLL, так и EXE-файлы. Параметр hFile второй функции не используется и должен быть равен нулю. В параметре dwFlags можно задать дополнительные параметры загрузки библиотеки, самый интересный из которых – флаг LOAD_LIBRARY_AS_DATAFILE, полезный при работе с ресурсами библиотеки. Возвращаемое значение – хэндл загруженного исполнимого модуля, применяемый для функций API, или 0 при неудачной загрузке.

После того, как библиотека больше не требуется, использующая программа должна освободить ее при помощи вызова функции

function FreeLibrary(module: hModule):boolean;

В качестве параметра передается хэндл модуля, полученный при загрузке библиотеки.

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

function GetProcAddress(module: hModule; procName: pChar): pointer;

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

pointer(10); - число 10, преобразованное к типу указатель

Возвращаемое значение – указатель на точку входа в процедуру или nil, если требуемая процедура отсутствует.

Использовать эту процедуру в программах на Паскале следует совместно с переменными процедурного типа (с указателями на процедуру), например так:

var Proc: procedure(a,b:integer); //процедура с двумя целыми параметрами hModule:THandle; ........................ hModule:=LoadLibrary('testlib.dll'); @Proc:=GetProcAddress(hmodule,'ProcedureTwo'); //настройка proc(1,2); // вызов FreeLibrary(hModule);

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

function GetModuleHandle(filename:PChar):HMODULE;

В качестве параметра необходимо передать имя файла уже загруженной библиотеки.