Явная загрузка библиотек

4.1. Загрузите дополнение, написанное в прошлом разделе, которое использует динамическую библиотеку. В основном модуле уберите объявление функции ShowAbout. Теперь в роздiлi type напишите объявление нового типа :

ShowA = function (Handle: THandle) : LongInt; stdcall;

 

Здесь мы объявляем новый тип ShowA, который равняется функции с параметрами функции showAbout из динамической библиотеки. Параметры должны быть точными, как при объявлении, иначе могут возникнуть проблемы.

 

4.2. Для события Onclick первой кнопки, написать следующий код.

procedure TForml.ButtonlClick (Sender: TObject);

var

DLLHandle: THandle;

sa: ShowA;

begin

if f> 0 then

FreeAbout (f);

DLLHandle: = LoadLibrary ( 'Proj ectDLL.DLL');

if DLLHandle = 0 then

exit; / / Библиотека не погрузилась

@ sa: = GetProcAddress (DLLHandle, 'ShowAbout');

if @ sa = nil then

exit; / / Функция не найдено

f: = sa (Handle);

FreeLibrary (DLLHandle);

end;

Здесь объявлены два локальные переменные:

DLLHandle - будет храниться указатель на зафуженную библиотеку;

sa - имеет тип ShowA, то есть тип функции из библиотеки.

В начале кода выполняется уже знакомая проверка переменной f. Если она больше нуля, то окно уже показывалось, и нужно освободить память от старого окна, прежде чем создавать новое.

Дальше вызывается функция LoadLibrary. Эта API -функція загружает отмеченную как параметр динамическую библиотеку в память. Результатом выполнения является указание на загруженную библиотеку. Этот указатель храним в переменной DLLHandie. После этого нужно проверить, если указатель DLLHandie равняется нулю, то библиотека не погрузилась.

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

- Указатель на загруженную библиотеку;

- Имя искомой процедуры.

Результатом будет адрес искомой функции, и мы его храним по адресу переменной @ sa. Теперь sa указывает по адресу, за которым загруженная процедура ShowAbout из динамической библиотеки. Единственное, что надо проверить, - корректность адреса. Если он равняется nil, то процедура не найдена (возможно, что это старая версия библиотеки или неправильно указано имя).

Если все нормально, то мы вызываем функцию через переменную f : = sa (Handle), почти так же, как это делалось раньше. Результат выполнения функции хранится в переменной f.

Последняя строка кода выгружает динамическую библиотеку из памяти - FreeLibrary.

 

Точка входа

В библиотеках есть одна глобальная переменная, которая существует всегда, и ее имя DLLProc. Это не просто переменная, а указатель на процедуру. За умалчиванием он равняется nil, но если сюда записать адрес реальной процедуры, то эта процедура может отзываться на определенные события, которые происходят в библиотеке. В процедуре можно регистрировать последующие события:

DLL_PROCESS_ATTACH - это событие генерируется при загрузке библиотеки.

DLL_PROCESS_DETACH - это событие генерируется при выгрузке библиотеки.

DLL_THREAD_ATTACH - при создании нового потока.

DLL_THREAD_DETACH - при отключении нового потока.

 

5.1. Откройте библиотеку, написанную в предыдущем разделе. Теперь добавляйте к ней код.

library ProjectDLL;

uses

SysUtils,

Classes,

Windows,

dialogs,

Unit1 in 'Unit1.pas' (Form1);

($ R *. RES)

exports ShowAbout index 10;

exports FreeAbout index 11;

procedure DLLEntryPoint (dwReason: DWord);

begin

case dwReason of

DLL_PROCESS_ATTACH : ShowMessage ( 'Attach to process');

DLL_PROCESS_DETACH : ShowMessage ( 'Detach to process');

DLL_THREAD_ATTACH : ShowMessage ( 'Thread attach to process');

DLL_THREAD_DETACH : ShowMessage ( 'Thread detach to process');

end;

end;

begin

DLLProc: = @ DLLEntryPoint;

DLLEntryPoint (DLL_PROCESS_ATTACH);

end.

 

В разделе uses появилось объявление двух новых модулей - windows и dialogs. Без них код не скомпіліруется. Немного дальше появилась процедура DLLEntryPoint с одним параметром, в котором будет передаваться событие, которое случилось. Внутри процедуры оператором case проверяется тип пришло сообщение и в зависимости от этого выводится сообщение.

Между begin и end библиотеки переменной DLLProc присваивается процедура. После этого вызываем ее и как параметр указываем событие DLL PROCESS ATTACH.

 








Дата добавления: 2016-02-27; просмотров: 492;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.006 сек.