Які бібліотеки dll копіюються під час встановлення delphi. Створення та використання динамічних бібліотек (DLL) у Delphi. Перегляд функцій певної DLL

Головна / Контакти

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

Для початку створимо нашу першу Dynamic Link Library! Вирушаємо в Delphiі відразу ж ліземо в меню File -> New -> Other.
Перед нами з'являється ось таке віконце:

Вибираємо у списку Dynamic-Link Library (у версіях молодших 2009 Delphiпункт називається DLL Wizard).

В результаті у нас з'являється лише вікно з кодом, зауважте жодної форми у нас тут немає!
Тепер починається найцікавіше. Напишемо наші перші процедури у бібліотеці.

library Project2;
//Ви, напевно, вже помітили, що замість program
//Під час створення dll використовується слово library.
/ / Що означає бібліотека.
uses
SysUtils, dialogs,
Classes; // Увага! Не забудьте вказати ці модулі,
// інакше код працювати не буде

($R *.res)
(У ЦЮ ЧАСТИНУ ПОМІЩУЄТЬСЯ КОД DLL)

Procedure FirstCall; stdcall; export;
//Stdcall - У цьому операторі параметри поміщаються у стек
// справа наліво, і вирівнюються на стандартне значення
//Експорт у принципі можна опустити, використовується для уточнення
//експорту процедури чи функції.

Begin
ShowMessage(" Моя перша процедура в dll");

End;

Procedure DoubleCall; stdcall; export;
Begin
ShowMessage(" Моя друга процедура");
//Викликаємо повідомлення на екран
End;

Exports FirstCall, DoubleCall;
//В Exports міститься список експортованих елементів.
// Які надалі імпортуватимуться якоюсь програмою.

begin
End.

На цьому ми поки що зупинимося т.к. для простого прикладу цього буде цілком достатньо. Зараз зберігаємо наш проект, особисто я зберіг його під ім'ям Project2.dll та натискаємо комбінацію клавіш CTRL+F9 для компіляції бібліотеки. У папці, куди ви зберегли dpr файл повинен з'явиться файл з розширенням dll, ця і є наша щойно створена бібліотека. У мене вона називається Project2.dll

Займемося тепер викликом процедур цієї бібліотеки. Створюємо за стандартною схемою нову програму. Перед нами нічого незвичайного просто форма. Зберігаємо новий додаток в якусь папку. І в цю ж папку копіюємо щойно створену dll бібліотеку. Тобто. в даному прикладі Project2.dll

Тепер вам доведеться вибирати, яким способом викликати функції бібліотеки. Усього існує два методи виклику.

Спосіб №1
Мабуть, це найпростіший метод виклику процедур, що знаходяться в бібліотеці.
Ідеально підходить для роботи лише з однією бібліотекою.

Ну що, поїхали...
Після ключового слова implementation прописуємо наступний код:

Procedure FirstCall; stdcall; external "Project2.dll";
// Замість Project2.dll може бути будь-яке ім'я бібліотеки

Procedure DoubleCall; stdcall; external "Project2.dll";

Тут, як ви вже напевно здогадалися, ми повідомляємо програму назви наших процедур і кажемо, що вони знаходяться в dll бібліотеців моєму випадку з ім'ям Project2.dll

Тепер для того, щоб викликати дані процедури, нам необхідно лише вставити їх назви в будь-яке місце коду, що ми зараз і зробимо. Кидаємо на форму 2 компоненти Button із закладки Standart і створюємо на кожній обробник подій OnClick

OnClick першої кнопки:


Begin
FirstCall;
End;

OnClick другої кнопки:


Begin
DoubleCall; // Ім'я процедури, яка знаходиться в dll
End;

От і все!

Спосіб №2:
Складніше ніж перший, але має свої плюси, а найголовніше, що він ідеально підходить для плагінів.
Для застосування даного методу, насамперед оголошуємо кілька глобальних змінних:

Var
LibHandle: HModule; //Посилання на модуль бібліотеки
FirstCall: procedure; stdcall;
//Імена наших процедур, що лежать у бібліотеці.

DoubleCall: procedure; stdcall;

Потім після ключового слова implementation напишемо процедуру, яка завантажуватиме нашу бібліотеку:

Procedure LoadMyLibrary(FileName: String);
Begin
LibHandle: = LoadLibrary (PWideChar (FileName));
//Завантажуємо бібліотеку!
// Увага! PChar для версій нижче 2009 Delphi
If LibHandle = 0 then begin
MessageBox(0,"",0,0);
Exit;
End;
FirstCall:= GetProcAddress(LibHandle,"FirstCall");
//Отримуємо покажчик на об'єкт
/ / Перший параметр посилання на модуль бібліотеки
//2-й параметр ім'я об'єкта в dll

DoubleCall:= GetProcAddress(LibHandle,"DoubleCall");
If @FirstCall = nil then begin

MessageBox(0," Неможливо завантажити бібліотеку",0,0);
Exit;
End;
If @DoubleCall = nil then begin
// Перевіряємо наявність цієї функції у бібліотеці.
MessageBox(0," Неможливо завантажити бібліотеку",0,0);
Exit;
End; End;

Після чого на формі створюємо, обробник подій OnCreate, в якому за допомогою щойно створеної процедури ми завантажимо нашу бібліотеку

Procedure TForm1.FormCreate(Sender: TObject);
Begin
LoadMyLibrary("Project2.dll");
End;

Тепер знову ж таки, для того, щоб викликати необхідні процедури з нашої бібліотеки, нам необхідно лише вставити їх назви в будь-яке місце коду. Для цього кидаємо на форму 2 компоненти Button із закладки Standart і створюємо на кожній обробник подій OnClick

OnClick першої кнопки:

Procedure TForm1.Button1Click(Sender: TObject);
Begin
FirstCall; // Ім'я процедури, яка знаходиться в dll
End;

OnClick другої кнопки:

Procedure TForm1.Button2Click(Sender: TObject);
Begin
DoubleCall; // Ім'я процедури, яка знаходиться в dll
End;

Ну і насамкінець створюємо обробник подій OnDestroy на формі, в якій вивантажуємо dll бібліотекуз пам'яті

Procedure TForm1.FormDestroy(Sender: TObject);
Begin
FreeLibrary (LibHandle);
//Вивантажуємо бібліотеку з пам'яті.
End;

От і все! Другий спосіб вийшов досить громіздкий, але його плюс в уточненні об'єкта, що зберігається в бібліотеці.

P.S. Хочете вперед решти відвідувачів сайту отримувати свіжі Відео уроки, Аудіо подкасти, статті по Delphi.
Брати участь у конкурсах і поступово вливатися до нашої команди?!
Тоді прямо зараз підписуйтесь на безкоштовну мультимедійну розсилку сайту
Нас уже понад 3500 осіб!

Використання DLL у Delphi
  • Концепція DLL
  • Створення DLL у Delphi (експорт)
  • Використання DLL у Delphi (імпорт)
  • DLL, що використовують об'єкти VCL для роботи з даними
  • Виняткові ситуації у DLL
  • Концепція DLL

Згадаймо процес програмування в DOS. Перетворення вихідного тексту програми в машинний код включав два процеси - компіляцію і лінковку. У процесі лінківки редактор зв'язків, що компонував окремі модуліпрограми, поміщав у код програми як оголошення функцій і процедур, а й повний код. Ви готували таким чином одну програму, іншу, третю... І скрізь код тих самих функцій поміщався в програму повністю.

Програма1 Програма2: : MyFunc(:) MyFunc(:) : : код функції MyFunc код функції MyFunc код інших функцій код інших функцій

У багатозадачному середовищі такий підхід був би щонайменше безрозсудним, оскільки очевидно, що величезна кількість тих самих функцій, відповідальних за промальовування елементів інтерфейсу користувача, за доступ до системних ресурсів і т.п. дублювалися б повністю у всіх додатках, що призвело б до швидкого виснаження найдорожчого ресурсу – оперативної пам'яті. Як вирішення проблеми, що виникла, ще на UNIX-подібних платформах була запропонована концепція динамічного компонування (див. рис. 2).

Але чим же відрізняються Dynamic Link Library (DLL) від звичайних додатків? Для розуміння цього потрібно уточнити поняття задачі (task), екземпляра (копії) програми (instance) та модуля (module).

При запуску кількох примірників однієї програми, Windows завантажує в оперативну пам'ятьтільки одну копію коду і ресурсів - модуль додатка, створюючи кілька окремих сегментів даних, стека та черги повідомлень (див. рис. 3), кожен набір яких представляє собою завдання, у розумінні Windows. Копія програми являє собою контекст, в якому виконується модуль програми.

DLL – бібліотека також є модулем. Вона знаходиться в пам'яті в єдиному екземплярі та містить сегмент коду та ресурси, а також сегмент даних (див. рис. 4).

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

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

Часто, як DLL створюються окремі набори функцій, об'єднані за тими чи іншим логічним ознаками, аналогічно тому, як концептуально відбувається планування модулів (у сенсі unit) в Pascal. Відмінність полягає в тому, що функції із модулів Pascal компонуються статично - на етапі лінківки, а функції з DLL компонуються динамічно, тобто в run-time.

Створення DLL у Delphi (експорт)

Для програмування DLL Delphi надає ряд ключових слівта правил синтаксису. Головне – DLL у Delphi такий самий проект як і програма.

Розглянемо шаблон DLL:


Ім'я файлу проекту для такого шаблону має бути MYDLL.DPR.

На жаль, у IDE Delphi автоматично генерується лише проект програми, тому Вам доведеться проект DLL готувати вручну. У Delphi 2.0 це незручність усунуто.

Як і в програмі, в DLL є розділ uses. Ініціалізаційна частина не є обов'язковою. У розділі exports перераховуються функції, доступ до яких повинен виконуватися із зовнішніх додатків.

Експортування функцій (і процедур) може здійснюватися кількома способами:

  • за номером (індексом)
  • по імені

Залежно від цього використовується різний синтаксис:


Так як у Windows існує поняття "резидентних функцій" DLL, тобто тих функцій, які знаходяться в пам'яті протягом усього часу існування DLL у пам'яті, у Delphi є засоби для організації та такого роду експорту:


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

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

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

Для наведених вище прикладів, у Вашій програмі слід оголосити функції, що імпортуються з DLL таким чином:


Цей метод називається статичним імпортом.

Як Ви могли помітити, розширення файлу, що містить DLL, не вказується - за промовчанням маються на увазі файли *.DLL та *.EXE. Як тоді бути у випадку, якщо файл має інше розширення (наприклад, як COMPLIB.DCL в Delphi), або якщо потрібно динамічне визначення DLL і імпортованих функцій (наприклад, Ваша програма працює з різними графічними форматамиі для кожного з них існує окрема DLL.)?

Для вирішення таких проблем Ви можете звернутися безпосередньо до API Windows, використовуючи так званий динамічний імпорт:


uses WinTypes, WinProcs, ...; type TMyProc = procedure ; var Handle: THandle; MyImportProc: TMyProc; begin Handle:= LoadLibrary("MYDLL"); if Handle >= 32 then (if begin@MyImportProc:= GetProcAddress(Handle, "MYEXPORTPROC"); if MyImportProc nil then ... (using imported procedure) end; FreeLibrary(Handle); end;

Синтаксичні діаграми оголошень експорту/імпорту, заміна точки виходу з DLL, та інші приклади, Ви можете знайти в OnLine Help Delphi, Object Pascal Language Guide, що входить до Borland RAD Pack for Delphi, і, наприклад, у книзі "Teach Yourself Delphi in 21 Days".

Якщо не говорити про код, що генерується компілятором (зараз він більш оптимізований), то всі правила синтаксису залишилися ті ж, що і в Borland Pascal 7.0

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

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

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

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


function MyFunc: string; begin try (Власне код функції) except on EResult: Exception do Result:=Format(DllErrorViewingTable, ) else Result:= Format(DllErrorViewingTable, ["Unknown error"]); end; end;

Код у програмі:


StrResult:= MyFunc; if StrResult "" then raise Exception.Create(StrResult);

Стаття Використання DLL у Delphiрозділу Файлова система DLL і PlugIns може бути корисним для розробників на Delphi і FreePascal.

Абревіатура DLLозначає " бібліотека, що динамічно з'єднується". Dll у Delphiце файл, що містить необхідні роботи комп'ютерної програмипроцедури та функції, з яким програма з'єднується на етапі виконання.

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

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

Створення бібліотеки DLL

Створення dll у Delphiне складніше створенняДодатковий модуль. Випонуйте команду File -> New -> -> Other... У діалоговому вікні, що з'явилося, виберіть піктограму DLL Wisard. В результаті Delphi створить заготівлю проекту бібліотеки DLL:

library Project1;

( Important note about DLL memory management: ShareMem must be the
перші unit в вашій library"s USES clause AND your project"s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings є параметрами або функціями результатів. This
applies to all strings passed to and from your DLL - even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. Для того, щоб використовувати BORLNDMM.DLL, pass string information
використовуючи PChar або ShortString parameters. )

uses
SysUtils,
Classes;

($R *.res)

begin
end
.

Виберіть ім'я для нової бібліотеки dll та збережіть в окрему папку, виконавши команду File -> Save As...У папці з'являться 4 файли, серед яких власне dll-файлу не буде. Звичайно, це просто текстові файли, що містять опис проекту Для створення підсумкового файлу бібліотеки dll необхідно скомпілювати проект. Виконайте команду Project -> Compile Project. В результаті в нашій папці з'явиться власне dll-файл, з яким і буде з'єднуватися основна програма.

Поки що це пуста бібліотека.

...тепер знаходиться в стадії редагування...



Вступ

У зв'язку з бурхливим розвитком технологій програмування все більше людей стикаються з проблемою нарощування можливостей своїх програм. Ця стаття присвячена саме цьому питанню, а саме – програмування DLL у Borland Delphi. Крім того, оскільки ми торкнемося питання щодо використання бібліотек DLL, то принагідно торкнемося імпортування функцій з чужих DLL (у тому числі і системних, тобто WinAPI).

Області застосування DLL

Отже, навіщо потрібні бібліотеки DLL і де вони використовуються?.. Перерахуємо лише деякі з областей їх застосування:

Окремі бібліотеки містять корисні для програмістів додаткові функції. Наприклад, функції для роботи з рядками, або складні бібліотеки для перетворення зображень. Сховища ресурсів У DLL можна зберігати як програми та функції, а й різноманітні ресурси - іконки, малюнки, рядкові масиви, меню, тощо. Бібліотеки підтримки Як приклад можна навести бібліотеки таких відомих пакетів, як: DirectX, ICQAPI (API для ICQ), OpenGL тощо. Частини програми Наприклад, у DLL можна зберігати вікна програми (форми) тощо. Плагіни (Plugins) Ось де справжній простір для думок програміста! Плагіни – доповнення до програми, що розширює її можливості. Наприклад, у цій статті ми розглянемо теорію створення плагіна для програми. Розділяється ресурс DLL (Dynamic Link Library) може бути використана відразу кількома програмами або процесами (т.зв. sharing - ресурс, що розділяється)

Короткий опис функцій та прийомів для роботи з DLL

Отже, які ж прийоми та функції необхідно використовувати, щоб працювати з DLL? Розберемо два методи імпортування функцій із бібліотеки:

1 спосіб. Прив'язка DLL до програми.

Це найпростіший і найлегший метод для використання функцій, що імпортуються з DLL. Однак (і на це слід звернути увагу) цей спосіб має дуже вагомий недолік – якщо бібліотека, яку використовує програма, не буде знайдена, то програма просто не запуститься, видаючи помилку та повідомляючи про те, що ресурс DLL не знайдено. А пошук бібліотеки вестиметься: у поточному каталозі, у каталозі програми, у каталозі WINDOWS\SYSTEM і т.д. Отже, для початку – загальна форма цього прийому:


FunctionName (або ProcedureName) - ім'я функції (або процедури), яке буде використовуватися у Вашій програмі; Par1, Par2, ... імена параметрів функції чи процедури; Par1Type, Par2Type, ... типи параметрів функції чи процедури (наприклад, Integer); ReturnType тип значення, що повертається (тільки для функції); stdcall директива, яка повинна точно збігатися з використовуваною в самій DLL; external "DLLNAME.DLL" директива, що вказує ім'я зовнішньої DLL, з якої буде імпортована дана функція або процедура (в даному випадку- DLLNAME.DLL); name "FunctionName" ("ProcedureName") директива, що вказує точне ім'я функції в самій DLL. Це необов'язкова директива, яка дозволяє використовувати в програмі функцію, що має назву, відмінну від істинної (яку вона має у бібліотеці); index FunctionIndex (ProcedureIndex) директива, що вказує порядковий номер функції або процедури в DLL. Це також необов'язкова директива.

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

LoadLibrary(LibFileName: PChar) завантажує вказану бібліотеку LibFileName у пам'ять. У разі успішного завершення функція повертає дескриптор (THandle) DLL у пам'яті. GetProcAddress(Module: THandle; ProcName: PChar) зчитує адресу експортованої бібліотечної функції. При успішному завершенні функція повертає дескриптор (TFarProc) функції у завантаженій DLL. FreeLibrary(LibModule: THandle) робить недійсним LibModule і звільняє пов'язану з ним пам'ять. Слід зазначити, що після цієї процедури функції цієї бібліотеки більше недоступні.

Практика та приклади

Ну а тепер настав час навести пару прикладів використання вищеперелічених методів і прийомів:

Приклад 1. Прив'язування DLL до програми


Тепер те саме, але другим способом - з динамічним завантаженням:


Примітка:

Слід утримуватися від використання типу string у бібліотечних функціях, т.к. при його використанні існують проблеми з "розподілом пам'яті". Докладніше про це можна прочитати (щоправда, англійською) у тексті порожнього проекту DLL, який створює Delphi (File -> New -> DLL). Так що краще використовуйте PChar, а потім за потреби конвертуйте його в string функцією StrPas.

А тепер розберемо безпосередньо саму бібліотеку DLL:

Приклад 3. Вихідник проекту MYDLL.DPR


Розміщення в DLL ресурсів та форм

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

Для цього потрібно створити нову DLL і додати до неї нову форму (File -> New -> DLL, а потім - File -> New Form). Далі, якщо форма є діалогове вікно (модальну форму (bsDialog)), то додаємо в DLL наступну функцію(припустимо, форма називається Form1, та її клас - TForm1):

Приклад 4. Розміщення форми у DLL


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

Створення плагінів

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

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

Епілог

У цій статті відображено основні сторони використання та створення бібліотек DLL у Borland Delphi. Якщо у Вас є питання – скидайте їх мені на E-mail:

У середовищі програмування Delphiпередбачені вбудовані засоби для швидкого створення DLL бібліотек.

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

GetArea(a, b, c: REAL): REAL.

Даною функцією на вхід подаються довжини сторін трикутника. Функція повертає площу заданого трикутника:

p:=(a+b+c)/2;

Result:=SQRT(p*(p-a)*(p-b)*(p-c))

Запускаємо Delphi, а далі діємо нетрадиційно. Вибираємо пункти меню FileNewOther, у віконці, що відкрилося на закладці Newклацаємо по піктограмі DLL Wizard. (алгоритм залежить від версії)

У цьому створюється файл заготівлі DLL-бібліотеки. Він дуже схожий на звичайний модуль (unit) Delphi, тільки починається з оператораLibrary. Збережіть проект під ім'ям, яке в майбутньому отримає DLL-бібліотека, скажімо,GetA. НазваGetAreaвикористовувати не можна – воно вже зайняте ім'ям функції.

Тепер після оператораUSESпишемо текст нашої функції, але з деякими змінами у заголовку:

FUNCTION GetArea(a, b, c:REAL):REAL;export;

Ключове слово EXPORT вказує на те, що ця функція є експортованою і буде видно із зовнішніх програм.

Після тексту функції припишемо

GetArea;

В операторі EXPORTS перераховуються всі процедури та функції, які експортуються з бібліотеки. Це свого роду каталог нашої бібліотеки.

Запустити на виконання бібліотеку неможливо, її можна лише відкомпілювати. Для цього виконаємо пункт меню Project → Build. Якщо все було зроблено правильно, на диску поточної директорії буде створено файл з ім'ям geta.dll. Це і наша бібліотека.

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

Для того, щоб можна було передавати параметри типу STRING, доведеться в оператори USES і бібліотеки, і програми, що викликає її, прописати підключення модуля ShareMem, та ще й обов'язково так, щоб цей модуль йшов першим у списку. Мало того, разом із бібліотекою доведеться обов'язково додавати файл borlndmm.dll (він входить у постачання Delphi). Уникнути цієї ситуації просто: слід для параметрів текстового типу використовувати типи даних ShortString (це звичайний рядок, але довжиною до 255 символів) та PChar (покажчик на текстовий рядок).

Виклик dll

Існують два способи виклику процедур та функцій з DLL. У першому випадку ми заздалегідь, на етапі розробки програми, знаємо, яку DLL будемо до неї підключати (найчастіше ми самі і створюємо цю DLL). У другому випадку ми підключаємося до довільної бібліотеки, у тому числі і "чужої".

Статичне зв'язування

Для реалізації першого способу, званого статичним зв'язуванням, створіть нову звичайну програму, помістіть на форму три поля введення LabeledEdit1…LabeledEdit3, кнопку та компонент Tlabel. Після оператора IMPLEMENTATION додайте рядок, який забезпечує імпорт функції GetArea з бібліотеки geta.dll:

Function GetArea (a, b, c: real): REAL; FAR; EXTERNAL "Geta";

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

У обробнику натискання кнопки треба створити масив і передати його бібліотечній функції, а результат вивести на екран:

procedure TForm1.Button1Click(Sender: TObject);

© 2022 androidas.ru - Все про Android