Новости

Створення і використання динамічних бібліотек (DLL) в Delphi.

Здрастуйте, шановні колеги!

У даній статті я постараюся відповісти на питання: Що таке DLL? Для чого вона потрібна? І як створювати і використовувати DLL за допомогою Delphi.

Що таке DLL?

Dynamic Link Library або скорочено DLL - це бібліотека, яка містить в собі набір даних або функцій для використання в інших програмах.

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

  • Зберігання ресурсів: іконки, звуки, курсори і т.д. Заощаджуємо на розмірі виконуваних файлів об'єднуючи ресурси в єдину бібліотеку.
  • Розміщення окремих модулів програми і форм інтерфейсу. Отримуємо можливість часткового оновлення програми, а при динамічному підключенні, можливо оновлювати модулі без перезапуску основної програми.
  • Використання в якості плагінів (PlugIn). Надаємо можливість розширювати функціонал додатка без переписування основного коду програми.
  • Бібліотека може використовуватися на різних мовах програмування в не залежності від мови, якою вона була написана.

Створення власної бібліотеки DLL.

Для створення бібліотеки заходимо в меню File -> Other і вибираємо Delphi Projects -> Dynamic-link Library.
Відкриється текст коду з заготівлею для створення бібліотеки:

library Project1; uses System.SysUtils, System.Classes; {$ R * .res} begin end.

Розміщення ресурсів

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

Додамо форму «Про програму».
Натискаємо File -> New -> VCL Form. Додамо текст і кнопку «ОК»: Додамо форму «Про програму»

Додамо функцію, яка буде виводити стандартний MessageBox з питанням, кнопками «Так», «Ні» і з результатом у вигляді True або False.

function YesNoDlg (const Question: PChar): boolean; stdcall; begin Result: = (MessageBox (0, Question, 'Підтвердження', MB_YESNO + MB_ICONQUESTION) = ID_YES); end;

Зверніть увагу на ключове слово stdcall. Воно визначає як саме будуть передаватися параметри і результати при виклику функцій. Більш докладно можна почитати на сторінці wiki Угода про виклик.

Так само додамо процедуру, яка буде використовуватися як плагін для основної програми. Яка буде додавати кнопку «Про програму» в основне меню програми для виклику створеного нами вікна.
Код процедури:

procedure PlugIn (Form: TForm); stdcall; var i: integer; mi: TMenuItem; begin for i: = 0 to Form.ComponentCount - 1 do begin if (Form.Components [i] .ClassName = 'TMenuItem') and (Form.Components [i] .Name = 'miHelp') then begin mi: = TMenuItem .Create (Form.Components [i]); mi.Caption: = 'Про програму'; mi.OnClick: = fmAbout.onAboutButtonClick; TMenuItem (Form.Components [i]). Add (mi); Exit; end; end; end;

В процедуру як параметр передається форма програми. Ми перевіряємо чи присутній на ній пункт меню з ім'ям «miHelp» і якщо меню знайшлося, то додаємо в нього свою кнопку.

Тепер зазначимо які функції і процедури можна використовувати з нашої бібліотеки.
Додамо рядок:

exports PlugIn, YesNoDlg;

Скомпілюємо функцію Project -> Build або за допомогою гарячої клавіші Shift + F9.
Якщо помилок в коді немає, то в папці проекту повинен з'явитися файл з розширенням DLL.

Тепер перейдемо до створення програми, яка буде використовувати нашу бібліотеку.

У додатку створимо форму Main в якій додамо компонент TMainMenu з наступними кнопками: Програма -> Вихід і Допомога. Для останнього задамо ім'я - miHelp: У додатку створимо форму Main в якій додамо компонент TMainMenu з наступними кнопками: Програма -> Вихід і Допомога

Перейдемо до коду форми.

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

Розглянемо статичний спосіб підключення:

... type TfmMain = class (TForm) MainMenu: TMainMenu; miProgram: TMenuItem; miExit: TMenuItem; miHelp: TMenuItem; procedure FormCreate (Sender: TObject); procedure miExitClick (Sender: TObject); private public end; procedure PlugIn (Form: TForm); stdcall; external 'SampleDLL.dll'; var ...

Ключове слово external вказує на те, що дана функція підключається з зовнішньої бібліотеки.

На подію onCreate форми додамо виклик процедури PlugIn:

procedure TfmMain.FormCreate (Sender: TObject); begin PlugIn (Self); end;

Як параметр Form передаємо в процедуру поточну форму (ключове слово Self).

При запуску програми у нас повинен з'явиться пункт «Про програму» в розділі «Допомога» головного меню.

Переходимо до динамічного способу підключення.

Нам знадобляться три функції WinApi:

LoadLibrary
Завантажує бібліотеку в пам'ять комп'ютера. Як результат повертає покажчик на бібліотеку в пам'яті. У разі помилки поверне 0.

LoadLibrary (lpLibFileName: LPCWSTR): HMODULE;

lpLibFileName - Файл бібліотеки.

GetProcAddress
Знайти функцію в бібліотеки на ім'я. Результатом буде покажчик на функцію. Якщо функція не знайдено, то поверне nil.

GetProcAddress (hModule: HMODULE; lpProcName: LPCSTR): FARPROC;

hModule - Покажчик на завантажену бібліотеку.
lpProcName - Ім'я функції.

FreeLibrary
Вивантажує бібліотеку з пам'яті комп'ютера. Результатом буде True в разі успішного виконання і False в разі помилки.

FreeLibrary (hLibModule: HMODULE): BOOL;

hLibModule - Покажчик на завантажену бібліотеку.

Тепер за допомогою динамічного способу отримаємо ресурси, нашу іконку і на кнопку «Вихід» додамо виклик функції YesNoDlg для підтвердження закриття програми.
На ту ж подію onCreate додаємо код:

procedure TfmMain.FormCreate (Sender: TObject); var DLLHandle: THandle; begin PlugIn (Self); DLLHandle: = LoadLibrary ( 'SampleDLL.dll'); if DLLHandle = 0 then raise Exception.Create ( 'Не вдалося підключити бібліотеку "SampleDLL"!'); try Self.Icon.LoadFromResourceName (DLLHandle, 'my_icon'); finally FreeLibrary (DLLHandle); end; end;

І на подію onClick пункту меню «Вихід»:

procedure TfmMain.miExitClick (Sender: TObject); var DLLHandle: THandle; Dlg: function (const Question: PChar): boolean; stdcall; begin DLLHandle: = LoadLibrary ( 'SampleDLL.dll'); if DLLHandle = 0 then raise Exception.Create ( 'Не вдалося підключити бібліотеку "SampleDLL"!'); try @Dlg: = GetProcAddress (DLLHandle, 'YesNoDlg'); if not Assigned (@Dlg) then raise Exception.Create ( 'Функція з ім'ям "YesNoDlg" не знайдено в бібліотеці "SampleDLL"!'); if Dlg ( 'Вийти з програми?') then Close; finally FreeLibrary (DLLHandle); end; end;

Якщо ви все написали правильно, то після запуску програми повинна змінитися іконка форми, додатися кнопка «Про програму», при натисканні на яку буде показувати форма About і на натискання кнопки вихід програма буде запитувати підтвердження: «Вийти з програми?».

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

Для чого вона потрібна?
Що таке DLL?

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: