Розробка DLL в Borland Delphi

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Якщо ваш комп'ютер працює під управлінням операційної системи Windows, то ви не можете не знати про існування динамічних під'єднуваних бібліотек (dynamic link libraries - DLL). Досить поглянути на список файлів, розташованих в системному каталозі Windows. Часом кількість використовуваних операційною системою динамічних бібліотек досягає декількох сотень. Таким чином, мені здається, не варто заперечувати той факт, що DLL є невід'ємною частиною функціонування операційних систем сімейства Microsoft Windows. Але ж для вас може бути неочевидна необхідність використання динамічних бібліотек при розробці додатків. У рамках даної статті ми поговоримо про принципи функціонування DLL і їх використання в процесі створення ваших власних програм.

Для початку давайте з'ясуємо, що собою являє динамічна бібліотека. Отже, DLL - це один або кілька логічно закінчених фрагментів коду, збережених у файлі з розширенням. Dll. Цей код може бути запущений на виконання в процесі функціонування будь-якої іншої програми (такі додатки називаються викликають по відношенню до бібліотеки), але сама DLL не є виконуваним файлом.

Існує два типи динамічних бібліотек - виконуються і бібліотеки ресурсів. Однак це не означає, що в одному файлі не може знаходитися і код деякої функції і будь-які ресурси. Просто іноді буває зручно рознести реалізацію виконуваних процедур і використовувані додатком ресурси в різні файли.

Отже, процедури та функції, що містяться у динамічній бібліотеці, можна розділити на два типи: ті, які можуть бути викликані з інших додатків. Розглянемо наступний приклад:

Screen.Cursors [myCursor]: = LoadCursor (HInstance, MYCURSOR ');

LoadCursor - функція Windows API, яка викликається додатком з динамічної бібліотеки User 32.dll. До речі, прикладом збережених у динамічній бібліотеці ресурсів можуть бути такі стандартні діалоги Windows, як діалог відкриття файлу, діалог друку або налаштування принтера. Ці діалоги знаходяться у файлі Comctl32.dll. Однак багато прикладні розробники використовують функції виклику форм цих діалогів, абсолютно не замислюючись, де зберігається їх опис.

Другий тип процедур - це ті, які використовуються тільки всередині самого файлу бібліотеки.

Аргументи на користь використання DLL

Отже, перш ніж перейти до обговорення структури динамічних бібліотек, необхідно поговорити про ті переваги, які надає їх використання розробнику. По-перше, це повторне використання коду. Думаю, немає потреби пояснювати зручність використання один раз розроблених процедур і функцій при створенні декількох додатків? Крім того, в подальшому ви зможете продати деякі зі своїх бібліотек, не розкриваючи вихідних кодів. А чим тоді це краще компонентів, запитаєте ви? А тим, що функції, що зберігаються в бібліотеці, можуть бути викликані на виконання з додатків, розроблених не на Object Pascal, а, наприклад, з використанням C + + Builder, Visual Basic, Visual C + + і т.д. Такий підхід накладає деякі обмеження на принцип розробки бібліотеки, але це можливо. Звучить заманливо? Мені здається, навіть дуже. Але це ще не все.

По-друге, використання DLL надає можливість використання один завантаженого в оперативну пам'ять коду декількома додатками. Наприклад, якщо ви розробляєте програмне забезпечення для великого підприємства, то цілком можливо, що в різних створених вами додатках будуть використовуватися одні й ті ж функції, процедури, форми та інші ресурси. Природно, що при виділенні загальних для декількох додатків даних в DLL може привести до економії як дискового простору, так і оперативної пам'яті, іноді дуже навіть істотного.

По-третє, слід поговорити ось про що. Лише кілька років тому при розробці програмного забезпечення ви могли зовсім не хвилюватися щодо розповсюдження ваших продуктів де-небудь, крім вашої країни. Я хочу сказати, що проблема перекладу на інші мови тексту на елементах управління (пункти меню, кнопки, списки, що випадають, підказки), повідомлень про помилки і т.д. не стояла так гостро, як зараз. Однак, з повсюдним впровадженням Інтернету у вас з'явилася можливість битрой передачі готових програмних продуктів практично в будь-яку точку світу. І що будуть робити з вашою програмою де-небудь в Об'єднаних Арабських Еміратах, якщо крім як по-російськи, вона з користувачем спілкуватися не вміє? Ви самі можете оцінити цей ефект, якщо хоч раз на екрані вашого комп'ютера замість з дитинства знайомого російської мови з'являється «арабська в'язь» (наприклад, через «збою» шрифтів). Отже, вже зараз ви повинні планувати можливість розповсюдження ваших додатків в інших країнах (якщо, звичайно, у вас є бажання отримати якомога більше прибутку). Відповідно, постає питання швидкого перекладу інтерфейсу вашої програми на інші мови. Одним із шляхів може бути створення ресурсів інтерфейсів всередині DLL. Наприклад, можна створити один додаток, який в залежності від версії динамічної бібліотеки буде виводити повідомлення на різних мовах.

Природно, вище наведені лише деякі з аргументів на користь використання динамічно підключаються при розробці додатків. Отже, сподіваюся, ви все ще зацікавлені в тому, щоб дізнатися, як власне, DLL створюються. Якщо так, то вперед.

Основи розробки DLL

Розробка динамічних бібліотек не є якимсь надскладний процес, доступний лише обраним. Якщо ви досить добре знайомі з розробкою додатків на Object Pascal, то вам не складе особливих труднощів навчитися працювати з механізмом DLL. Отже, розглянемо ті особливості створення DLL, які вам необхідно знати, а в завершенні статті розробимо свою власну бібліотеку.

Як і будь-який інший модуль, модуль динамічної бібліотеки має фіксований формат. Погляньте на лістинг, представлений нижче.

library MyFirstDLL;

uses

SysUtils,

Classes,

Forms,

Windows;

procedure HelloWorld (AForm: TForm);

begin

MessageBox (AForm.Handle, Hello world! ',

DLL Message Box ', MB_OK or MB_ICONEXCLAMATION);

end;

exports

HelloWorld;

begin

end.

Перше, на що слід звернути увагу, це ключове слово library, що знаходиться вгорі сторінки. Library визначає цей модуль як модуль бібліотеки DLL. Далі йде назва бібліотеки. У нашому прикладі ми маємо справу з динамічним бібліотекою, яка містить єдину процедуру: HelloWorld. Причому зверніть увагу, що дана процедура по структурі нічим не відрізняється від тих, які ви ставите в модулі своїх додатків. Ключове слово exports сигналізує компілятору про те, що перераховані нижче функції та / або процедури повинні бути доступні з викликають додатків (тобто вони як би «експортуються» з бібліотеки). Детальніше про механізм експорту ми поговоримо трохи пізніше.

І, нарешті, в кінці модуля можна побачити ключові слова begin і end. Всередині цього блоку ви можете помістити код, який повинен виконуватися в процесі завантаження бібліотеки. Досить часто цей блок залишається порожнім.

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

Опис і реалізація процедур і функцій, що викликаються в межах поточної DLL, нічим не відрізняються від їх аналогів в звичайних проекти-додатках. Їх специфіка полягає лише в тому, що викликає програма не буде мати до них доступу. Вона просто не буде нічого знати про їх існування, так само, як одні класи нічого не знають про ті методи, які описані в секції private інших класів.

На додаток до процедур і функцій, DLL може містити глобальні дані, доступ до яких дозволений для всіх процедур і функцій в бібліотеці. Для 16-бітних додатків ці дані існували в єдиному екземплярі незалежно від кількості завантажених в оперативну пам'ять програм, які використовують поточну бібліотеку. Іншими словами, якщо одна програма змінює значення глобальної змінної a на 100, то для всіх інших додатків a буде значення 100. Для 32-бітних додатків це не так. Тепер для кожного додатка створюється окрема копія глобальної області даних.

Експорт функцій з DLL

Як вже говорилося вище, для експорту процедур і функцій з DLL, необхідно використовувати ключове слово export. Ще раз зверніть увагу на представлений вище лістинг бібліотеки MiFirstDll. Оскільки процедура HelloWorld визначена як експортується, то вона може бути викликана на виконання з інших бібліотек чи додатків. Існують наступні способи експорту процедур і функцій: експорт по імені і експорт за порядковим номером.

Найбільш поширений спосіб експорту - на ім'я. Погляньмо на наведений нижче текст:

exports

SayHello,

DoSomething,

DoSomethingReallyCool;

Слід звернути увагу на те, що Delphi автоматично призначає порядковий номер кожного експортується функції (процедури) незалежно від того, визначаєте ви його явно чи ні. Явна визначення індексу дозволяє вам особисто керувати порядковим номером експортується функції або процедури.

Для того, щоб визначити чи виконується ваш кодек в DLL або в зухвалій додатку, можна скористатися глобальної змінної IsLibrary. Вона приймає значення ІСТИНА в тому випадку, якщо код викликається з бібліотеки і БРЕХНЯ в разі виконання процедури або функції з викликає додатки.

Крім цього, в постачання Delphi входить дуже корисна утиліта tdump, яка надає дані про те, яка інформація експортується з вказаної DLL.

Використання DLLProc

Вище я вже говорив про те, що код ініціалізації динамічної бібліотеки може бути поміщений в блок begin ... end. Однак крім цього найчастіше необхідно передбачити деякі дії, що їх у процесі вивантаження DLL з оперативної пам'яті. На відміну від інших типів модулів, модуль DLL не має ні секції initialization, ні секції finalization. Наприклад, ви можете динамічно виділити пам'ять у головному блоці, проте не зрозуміло, де ця пам'ять повинна бути звільнена. Для вирішення цієї проблеми існує DLLProc - спеціальна процедура, що викликається в певні моменти функціонування DLL.

Для початку слід сказати про саму причини існування DLLProc. Динамічна бібліотека отримує повідомлення від EN-US '> Windows в моменти своєї завантаження і вивантаження з оперативної пам'яті, а також у тих випадках, коли який-небудь черговий процес, що використовує функції та / або ресурси, що зберігаються в бібліотеці, завантажується в пам'ять. Така ситуація можливо в тому випадку, коли бібліотека необхідна для функціонування декількох style = "mso-spacerun: yes"> љ додатків. А для того, щоб ви мали можливість вказувати, що саме має відбуватися в такі моменти, необхідно описати спеціальну процедуру, яка і буде відповідальна за такі дії. Наприклад, вона може виглядати наступним чином:

procedure MyFirstDLLProc (Reason: Integer);

begin

if Reason = DLL_PROCESS_DETACH then

{DLL is unloading. Cleanup code here.}

end;

Проте системі абсолютно не очевидно, що саме процедура MyFirstDllProc відповідальна за обробку розглянутих вище ситуацій. Тому ви повинні поставити у відповідність адресу нашої процедури глобальної змінної DLLProc. Це необхідно зробити в блоці begin ... end приблизно так:

begin

DLLProc: = @ MyDLLProc;

{Що-небудь ще, що повинно виконуватися в

процесі ініціалізації бібліотеки}

end.

Нижче представлений код, що демонструє один з можливих варіантів застосування DLLProc.

library MyFirstDLL;

uses

SysUtils,

Classes,

Forms,

Windows;

var

SomeBuffer: Pointer;

procedure MyFirstDLLProc (Reason: Integer);

begin

if Reason = DLL_PROCESS_DETACH then

{DLL is вивантажується з пам'яті.

Звільняємо пам'ять, виділену під буфер.}

FreeMem (SomeBuffer);

end;

procedure HelloWorld (AForm: TForm);

begin

MessageBox (AForm.Handle, Hello world! ',

DLL Message Box ', MB_OK or MB_ICONEXCLAMATION);

end;

{Який-небудь код, в якому використовується SomeBuffer.}

exports

HelloWorld;

begin

{Ставимо у відповідність змінної

DLLProc адресу нашої процедури.}

DLLProc: = @ MyFirstDLLProc;

SomeBuffer: = AllocMem (1024);

end.

Як можна побачити, як ознака того чи іншого події, в результаті якої викликається процедура MyFirstDll, є значення змінної Reason. Нижче наведені можливі значення цієї змінної.

DLL_PROCESS_DETACH - бібліотека вивантажується з пам'яті; використовується один раз;

DLL_THREAD_ATTACH - в оперативну пам'ять завантажується новий процес, що використовує ресурси і / або код з даної бібліотеки;

DLL_THREAD_DETACH - один з процесів, які використовують бібліотеку, 'вивантажується' з пам'яті.

Завантаження DLL

Перш ніж почати використання будь-якої процедури або функції, що знаходиться у динамічній бібліотеці, вам необхідно завантажити DLL в оперативну пам'ять. Завантаження бібліотеки може бути здійснена одним з двох способів: статичне завантаження і динамічне завантаження. Обидва методи мають як переваги, так і недоліки.

Статична завантаження означає, що динамічна бібліотека завантажується автоматично при запуску на виконання використовує її застосування. Для того щоб використовувати такий спосіб завантаження, вам необхідно скористатися ключовим словом external при описі експортується з динамічної бібліотеки функції або процедури. DLL автоматично завантажується при старті програми, і Ви зможете використовувати будь-які експортуються з неї підпрограми точно так само, як якщо б вони були описані всередині модулів програми. Це найбільш легкий спосіб використання коду, поміщеного в DLL. Недолік методу полягає в тому, що якщо файл бібліотеки, на який є посилання в додатку, відсутній, програма відмовиться завантажуватися.

Сенс динамічного методу полягає в тому, що ви завантажуєте бібліотеку не при старті програми, а в той момент, коли вам це дійсно необхідно. Самі посудіть, адже якщо функція, описана у динамічній бібліотеці, використовується тільки при 10% запусків програми, то абсолютно немає сенсу використовувати статичний метод завантаження. Вивантаження бібліотеки з пам'яті в даному випадку також здійснюється під вашим контролем. Ще одне переваги такого способу завантаження DLL - це зменшення (зі зрозумілих причин) часу старту вашого застосування. А які ж у цього способу є недоліки? Основною, як мені здається, - це те, що використання даного методу є більш важким, ніж розглянута вище статичне завантаження. Спочатку вам необхідно скористатися функцією Windows API LoadLibrary. Для отримання покажчика на експортованої процедури або функції повинна використовуватися функція GetProcAddress. Після завершення використання бібліотеки DLL повинна бути вивантажено із застосуванням FreeLibrary.

Виклик процедур і функцій, завантажених з DLL.

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

Доступ до функцій і процедур з статично завантажених DLL досить простий. Спочатку в додатку має міститися опис експортується функції (процедури). Після цього ви можете їх використовувати точно так само, як якщо б вони були описані в одному з модулів вашої програми. Для імпорту функції або процедури, що міститься в DLL, необхідно використовувати модифікатор external в їх оголошенні. Наприклад, для розглянутої нами вище процедури HelloWorld в зухвалій додатку повинна бути поміщена такий рядок:

procedure SayHello (AForm: TForm); external myfirstdll.dll ';

Ключове слово external повідомляє компілятору, що дана процедура може бути знайдена у динамічній бібліотеці (у нашому випадку - myfirstdll.dll). Далі виклик цієї процедури виглядає наступним чином:

...

HelloWorld (self);

...

При імпорті функції і процедур будьте особливо уважні при написанні їхніх імен і інтерфейсів! Справа в тому, що в процесі компіляції програми не проводиться перевірки на правильність імен об'єктів, що експортуються з DLL, здійснюватися не буде, і якщо ви неправильно описали яку-небудь функцію, то виключення буде згенеровано тільки на етапі виконання програми.

Імпорт з DLL може проводитися на ім'я процедури (функції), порядковому номеру або з присвоєнням іншого імені.

У першому випадку ви просто оголошуєте ім'я процедури і бібліотеку, з якої її імпортуєте (ми це розглянули трохи вище). Імпорт за порядковим номером вимагає від вас зазначення цього самого номера:

procedure HelloWorld (AForm: TForm);

external myfirstdll.dll 'index 15;

У цьому випадку ім'я, яке ви даєте процедурою при імпорті не обов'язково має збігатися з тим, яке було визначено для неї в самій DLL. Тобто наведена вище запис означає, що ви імпортуєте з динамічної бібліотеки myfirstdll.dll процедуру, яка в ній експортувалася п'ятнадцятій, і при цьому в рамках вашого застосування цієї процедури дається ім'я SayHello.

Якщо ви з якихось причин не застосовуєте описаний вище спосіб імпорту, але тим не менш хочете змінити ім'я імпортованої функції (процедури), то можна скористатися третім методом:

procedure CoolProcedure;

external myfirstdll.dll 'name DoSomethingReallyCool';

Тут імпортованої процедурі CoolProcedure дається ім'я DoSomethingReallyCool. Виклик процедур і функцій, що імпортуються з динамічно завантажуваних бібліотек кілька більш складний, ніж розглянутий нами вище спосіб. У даному випадку потрібно оголосити покажчик на функцію або процедуру, яку ви збираєтеся використовувати. Пам'ятайте процедуру HelloWorld? Давайте подивимося, що необхідно зробити для того, щоб викликати її на виконання в разі динамічного завантаження DLL. По-перше, вам необхідно оголосити тип, який описував би цю процедуру:

type

THelloWorld = procedure (AForm: TForm);

Тепер ви повинні завантажити динамічну бібліотеку, за допомогою GetProcAddress отримати вказівник на процедуру, викликати цю процедуру на виконання, і, нарешті, вивантажити DLL з пам'яті. Нижче приведений код, який демонструє, як це можна зробити:

var

DLLInstance: THandle;

HelloWorld: THelloWorld;

begin

{Завантажуємо DLL}

DLLInstance: = LoadLibrary (myfirstdll.dll ');

{Отримуємо покажчик}

@ HelloWorld: = GetProcAddress (DLLInstance, HelloWorld ');

{Викликаємо процедуру на виконання}

HelloWorld (Self);

{Вивантажуємо DLL з оперативної пам'яті}

FreeLibrary (DLLInstance);

end;

Як вже говорилося вище, одним з недоліків статичної завантаження DLL є неможливість продовження роботи програми при відсутності однієї або декількох бібліотек. У випадку з динамічної завантаженням у вас з'являється можливість програмно обробляти такі ситуації і не допускати, щоб програма «випадали» самостійно. По поверненню функціями LoadLibrary і GetProcAddress значенням можна визначити, чи успішно пройшла завантаження бібліотеки і знайдена в ній необхідна додатком процедура. Наведений нижче код демонструє це.

procedure TForm1.DynamicLoadBtnClick (Sender: TObject);

type

THelloWorld = procedure (AForm: TForm);

var

DLLInstance: THandle;

HelloWorld: THelloWorld;

begin

DLLInstance: = LoadLibrary (myfirstdll.dll ');

if DLLInstance = 0 then begin

MessageDlg (Неможливо завантажити DLL ', mtError, [mbOK], 0);

Exit;

end;

@ HelloWorld: = GetProcAddress (DLLInstance, HelloWorld ');

if @ HelloWorld nil then

HelloWorld (Self)

else

MessageDlg (Не знайдена шукана процедура!. ', MtError, [mbOK], 0);

FreeLibrary (DLLInstance);

end;

У DLL можна зберігати не тільки код, але й форми. Причому створення і приміщення форм в динамічну бібліотеку не занадто сильно відрізняється від роботи з формами в звичайному проекті. Спочатку ми розглянемо, яким чином можна написати бібліотеку, яка містить форми, а потім ми поговоримо про використання технології MDI в DLL.

Розробку DLL, що містить форму, я продемонструю на прикладі.

Отже, по-перше, створимо новий проект динамічної бібліотеки. Для цього виберемо пункт меню File | New, а потім двічі клацнемо на іконку DLL. Після цього ви побачите приблизно наступний код:

library Project2;

{Тут були коментарі}

uses

SysUtils,

Classes;

{$ R *. RES}

begin

end.

Збережіть отриманий проект. Назвемо його DllForms.dpr.

Тепер слід створити нову форму. Це можна зробити по-різному. Наприклад, вибравши пункт меню File | New Form. Додайте на форму які-небудь компоненти. Назвемо форму DllForm і збережемо отриманий модуль під ім'ям DllFormUnit.pas.

Повернемося до головного модулю проекту і помістимо в нього функцію ShowForm, у завдання якої входитиме створення форми та її виведення на екран. Використовуйте для цього наведений нижче код.

function ShowForm: Integer; stdcall;

var

Form: TDLLForm;

begin

Form: = TDLLForm.Create (Application);

Result: = Form.ShowModal;

Form.Free;

end;

Звертаю увагу, що для того, щоб проект був скомпільований без помилок, необхідно додати в секцію uses модуль Forms.

Експортуємо нашу функцію з використанням ключового слова exports:

exports

ShowForm;

Компілюємо проект і отримуємо файл dllforms.dll. Ці прості кроки - все, що необхідно зробити для створення динамічної бібліотеки, яка містить форму. Зверніть увагу, що функція ShowForm оголошена з використанням ключового слова stdcall. Воно сигналізує компілятору використовувати при експорті функції угоду по стандартному викликом (standard call calling convention). Експорт функції таким чином створює можливість використання розробленої DLL не тільки в додатках, створених в Delphi.

Угода за викликом (Calling conventions) визначає, яким чином передаються аргументи при виклику функції. Існує п'ять основних угод: stdcall, cdecl, pascal, register і safecall. Детальніше про це можна дізнатися, подивившись розділ "Calling Conventions" у файлі допомоги Delphi.

Також зверніть увагу, що значення, яке повертається функцією ShowForm, відповідає значенню ShowModal. Таким чином ви можете передавати деяку інформацію про стан форми зухвалому додатком.

Нижче представлено два лістингу, перший з яких містить повний код файлу проекту DLL (модуль з формою тут не наводиться), а другий - модуль викликає програми, в якому використовується тільки що розроблена нами бібліотека.

library DllForms;

uses

SysUtils,

Classes,

Forms,

DllFormUnit in 'DllFormUnit.pas' {DllForm};

{$ R *. RES}

function ShowForm: Integer; stdcall;

var

Form: TDLLForm;

begin

Form: = TDLLForm.Create (Application);

Result: = Form.ShowModal;

Form.Free;

end;

begin

end.

unit TestAppUnit;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

type

TForm1 = class (TForm)

Button1: TButton;

procedure Button1Click (Sender: TObject);

private

{Private declarations}

public

{Public declarations}

end;

var

Form1: TForm1;

function ShowForm: Integer; stdcall;

external dllforms.dll ';

implementation

{$ R *. DFM}

procedure TForm1.Button1Click (Sender: TObject);

begin

ShowForm;

end;

end.

Прошу зауважити, що при експорті функції також було використано ключове слово stdcall.

Слід звернути особливу увагу на роботу з дочірніми формами в DLL. Якщо, приміром, в зухвалій додатку головна форма має значення властивості FormStyle, рівним MDIForm, то при спробі дзвінка з DLL MDIChild-форми, на екрані з'явиться повідомлення про помилку, у якому буде говоритися, що немає жодної активної MDI-форми.

У той момент, коли ви намагаєтеся показати ваше дочірнє вікно, VCL перевіряє коректність властивості FormStyle головної форми додатка. Однак у нашому випадку все начебто правильно. Так у чому ж справа? Проблема в тому, що при проведенні такої перевірки, розглядається об'єкт Application, що належить не викликає додатком, а власне динамічній бібліотеці. Ну, і природно, оскільки в DLL немає головної форми, перевірка видає помилку. Для того щоб уникнути такої ситуації, треба призначити об'єкту Application динамічної бібліотеки об'єкт Application викликає додатки. Природно, це запрацює тільки в тому випадку, коли викликає програма - VCL-додаток. Крім того, перед вивантаженням бібліотеки з пам'яті необхідно повернути значення об'єкта Application бібліотеки в первинний стан. Це дозволить менеджеру пам'яті очистити оперативну пам'ять, займану бібліотекою. Отже, вам потрібно зберегти покажчик на «рідній» для бібліотеки об'єкт Application в глобальній змінній, яка може бути використана при відновленні його значення.

Отже, повернемося трохи назад і перерахуємо кроки, необхідні нам для роботи з поміщеним у DLL MDIChild-формами.

У динамічній бібліотеці створюємо глобальну змінну типу TApplication.

Зберігаємо покажчик на об'єкт Application DLL в глобальної змінної.

Об'єкту Application динамічної бібліотеки ставимо у відповідність покажчик на Application викликає додатки.

Створюємо MDIChild-форму і працюємо з нею.

Повертаємо в первісний стан значення об'єкта Application динамічної бібліотеки та вивантажуємо DLL з пам'яті.

Перший крок простий. Просто поміщаємо наступний код у верхній частині модуля DLL:

var

DllApp: TApplication;

Потім створюємо процедуру, яка буде змінювати значення об'єкта Application і створювати дочірню форму. Процедура може виглядати приблизно так:

procedure ShowMDIChild (MainApp: TApplication);

var

Child: TMDIChild;

begin

if not Assigned (DllApp) then begin

DllApp: = Application;

Application: = MainApp;

end;

Child: = TMDIChild.Create (Application.MainForm);

Child.Show;

end;

Все, що нам тепер необхідно зробити, - це передбачити повернення значення об'єкта Application в початковий стан. Робимо це за допомогою процедури MyDllProc:

procedure MyDLLProc (Reason: Integer);

begin

if Reason = DLL_PROCESS_DETACH then

{DLL is вивантажується. Відновлюємо значення покажчика Application}

if Assigned (DllApp) then

Application: = DllApp;

end;

Замість висновку.

Використання динамічно підключаються не так складно, як це може здатися на перший погляд. DLL надають найширші можливості для оптимізації роботи додатків, а також роботи самих програмістів. Використовуйте DLL і, можливо, ваше життя стане легше!

Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Реферат
46.9кб. | скачати


Схожі роботи:
Розробка програми на мові Borland Object Pascal Ide Borland Delphi
Середовище програмування Borland Delphi
Середовище програмування Borland Delphi
Borland Delphi 7 міграція в бік Net
Розробка алгоритмів та програмування різних обчислювальних процесів на мові Delphi
Розробка бази даних для інформатизації діяльності підприємства малого бізнесу Delphi 70
Розробка бази даних для інформатизації діяльності підприємства малого бізнесу Delphi 7 0
Жорстке впровадження DLL в Windows-програми
Borland C Builder
© Усі права захищені
написати до нас