Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект лекций РСОИ.doc
Скачиваний:
20
Добавлен:
04.11.2018
Размер:
1.93 Mб
Скачать

2.1.3. Використання dll у Delphi (імпорт)

Для організації імпорту, тобто доступу до функцій, експортованих з DLL, Delphi надає стандартні засоби.

Статичний (неявний) виклик

У секції програми, що викликає DLL, необхідно оголосити функції, імпортовані з DLL у такий спосіб:

{ імпорт за специфікованим іменем }

procedure <ім’я_процедури>; external '<шлях_до_DLL>' name '<ім’я_за_експортом>';

Наприклад:

procedure ImpProc1; external 'MYDLL' name 'MYEXPORTPROC';

{ імпорт за індексом }

procedure <ім’я_процедури>; external '<шлях_до_DLL>' index <індекс_за_експортом>;

Наприклад:

procedure ImpProc1; external 'MYDLL' index 10;

{ імпорт за оригінальним іменем }

procedure <ім’я_процедури>; external '<шлях_до_DLL>';

Наприклад:

procedure MyExportFunc1; external 'MYDLL';

Аналогічно здійснюється імпорт функцій.

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

Динамічний (явний) виклик

Розширення файла, що містить DLL, не вказується − за замовчуванням маються на увазі файли *.DLL і *.ЕХЕ. Якщо файл має інше розширення (наприклад, як COMPLIB.DCL у Delphi), або якщо потрібне динамічне визначення DLL і імпортованих функцій, використовують динамічне підключення DLL.

Нижче наведено фрагмент програмного модуля з демонстрацією динамічного підключення DLL.

uses

WinTypes, WinProcs, ... ;

Type

// оголошення процедурного типу, що співпадає з прототипом

//оголошеного в DLL методу

TMyProc = procedure() ;

var

Handler : THandle; // оголошення дескриптора бібліотеки

MyImportProc : TMyProc; // оголошення змінної процедурного типу

begin

// пошук та завантаження DLL

Handler:=LoadLibrary('MYDLL');

if Handler>=32 then { if <=32 - error ! }

begin

// формування вказівника на імпортований метод

MyImportProc:=GetProcAddress(Handler,'MYEXPORTPROC');

if @MyImportProc<>nil then

...... {using imported procedure}

end;

FreeLibrary(Handler); // звільнення бібліотеки

end;

Далі в програмі виконується звичайне звертання до імпортованих методів.

DLL, що використовує об’єкти VCL для роботи з формами

Форми в DLL необхідно створювати “вручну”, наприклад:

Procedure ShowForm(AOwner:TComponent);

begin

DemoForm := TDemoForm.Create(Aowner);

DemoForm.ShowModal;

DemoForm.Free;

end;

Параметр AOwner є вказівником на батьківське вікно форми (батьківський застосунок).

Програма-користувач DLL має:

1) оголосити таку процедуру

Procedure ShowForm(AOwner:TComponent); external ’mydll.dll’;

2) розробити процедуру звертання до неї за деякою подією, наприклад:

Procedure Form1.Button1Click(Sender:TObject);

begin

ShowForm(Application);

end;

DLL, що використовує динамічні змінні

Якщо DLL використовує змінні або функції, які приводять до необхідності динамічного використання оперативної пам’яті (довгі рядки, або динамічні масиви, або функції GetMemo), вони повинні обов’язково використовувати модуль SHAREMEM. Модуль має вказуватися двічі: в самій DLL наведеним першим у списку модулів секції uses, а також у файлі проекту клієнта.

DLL, що використовує об’єкти VCL для роботи з базами даних

При створенні своєї динамічної бібліотеки можна використовувати виклики функцій з інших DLL. Приклад такої DLL є в інсталяційному пакеті Delphi (X:\Delphi\DEMOS\BD\BDEDLL). Ця DLL містить форму, що відображає дані з таблиці і використовує для доступу до неї об’єкти VCL (ТТable, TDBGrid, ТSession), які, у свою чергу, викликають функції BDE. Для такої DLL існує обмеження: її не можуть одночасно використовувати кілька задач. Це пояснюється тим, що об’єкт Session, який створюється автоматично при підключенні модуля DB, ініціюється для модуля, а не для задачі. Якщо спробувати завантажити цю DLL удруге з іншого застосунка, то виникне помилка. Для запобігання одночасного завантаження DLL декількома задачами необхідно здійснити деякі дії. Наприклад, розробити процедуру перевірки того, чи використовується DLL у цей момент іншою задачею.

Виняткові ситуації в DLL

Виникнення виняткової ситуації в DLL, створеної в Delphi, призведе до припинення виконання всього застосунка, якщо ця ситуація не була оброблена всередині DLL. Тому бажано передбачити всі можливі неприємності на момент розробки DLL. Можна порекомендувати повертати результат виконання імпортованої функції у вигляді рядка або числа і, при необхідності, наново викликати виняткову ситуацію в програмі.

//Код у DLL, що дозволяє обробляти виняткові ситуації

function MyFunc : string;

begin

try {код функції}

except

on EResult: Exception do

Result:=Format(DllErrorViewingTable, [EResult.Message]);

else

Result := Format(DllErrorViewingTable, ['Unknown error']);

end;

end;

// Відповідний код у програмі-користувачі DLL:

StrResult:=MyFunc;

if StrResult <> ’’ then

//Якщо в DLL виникла виняткова ситуація

raise Exception.Create(StrResult);