Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП (13.динамические библиотеки у.doc
Скачиваний:
1
Добавлен:
11.11.2019
Размер:
135.68 Кб
Скачать

Лекція 13:

Тема: Бібліотеки. Використання існуючих бібліотек. Створення бібліотек. Бібліотеки в пам’яті.

План:

  1. Бібліотека DLL

  2. Робота з динамічними бібліотеками в DELPHI.

  3. Створення динамічної бібліотеки.

  4. Наповнення бібліотеки вмістом.

  5. Підключення бібліотеки до програми

  6. Завантаження бібліотеки в пам'ять.

  7. Зберігання ресурсів в динамічній бібліотеці

Звичайне програма в Delphi складається з програмних одиниць (модулів, units). У цих модулях знаходяться початкові коди процедур і функцій, визначення типів даних і тому подібне Звичайне програма крім модулів, написаних розробником (як правило, поодинці на форму), включає безліч стандартних модулів, що реалізовують базову функціональність приложени і стандартних елементів інтерфейсу. Коли розробка програма добігає кінця, програміст запускає компіляцію проекту, і Delphi компілірує всі модулі і викликає компонувальник, щоб зібрати їх в оди виконуваний файл ЕХЕ.

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

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

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

Динамічні бібліотеки відрізняються від статичних двома основними ознаками:

  • динамічна бібліотека підключається до програми під час виконання, в той момент, коли програма викликає функцію, код якої знаходиться в цій бібліотеці;

  • динамічна бібліотека може бути такою, що розділяється, тобто декілька програм можуть підключати одну і ту ж бібліотеку.

По цих причинах DLL бібліотеки використовуються дуже часто і є, власне, одним з основних елементів самої Windows.

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

Робота з динамічними бібліотеками в DELPHI

Створення динамічної бібліотеки

Динамічна бібліотека відрізняється від звичайної програми — у неї немає головного вікна, вона не містить компонентів і тому подібне Відрізняється і спосіб її створення в Delphi.

  1. У рядку меню Delphi виберіть команду FileNewOther. У діалоговому вікні New Items, що з'явилося, перейдіть на вкладку New і виберіть DLL Wizard. Натисніть ОК.

  2. Відкриється вікно редактора коди із заготівкою порожньої бібліотеки (див. лістинг).

Лістинг Заготівка динамічної бібліотеки

library Projectl;

{коментар}

uses

SysUtils

Classes;

{$R

res}

begin end.

Найпомітнішою частиною заготівки проекту бібліотеки є коментар. Він містить попередження про те, що, якщо в бібліотеці будуть реалізовані процедури або функції, що повертають або приймають як аргумент дані типу String, то першим в списку використовуваних модулів (у секції Uses) повинен стояти модуль ShareMem. Цим модулем є інтерфейс до динамічної бібліотеки BORLNDMM.DLL, що управляє сумісним використанням пам'яті. Якщо ви плануєте поширювати свою динамічну бібліотеку, то BORLNDMM.DLL повинна розповсюджуватися разом з нею.

Зверніть увагу, що на початок початкової коди замість ключових слів Program або Unit коштує ключове слово Library, вказуюче, що проект повинен бути зібраний як бібліотека.

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

Наповнення бібліотеки вмістом

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

Одна повертатиме факторіал числа, інша — поточний рік (з системної дати). Для ілюстрації ініціалізації бібліотеки помістимо в секцію ініціалізації виведення вітального повідомлення, для чого в секцію! Uses додамо модуль Dialogs (лістинг).

Лістинг: Наповнюємо бібліотеку:

library Projectl; { коментар }

SysUtils, Classes, Dialogs;

{$r *.res}

function Factorial(N: Integer): Double;

var

I: Integer; begin

Result := 1.0;

for I := N downto 2 do Result := Result * I; end;

function GetCurrentYear: Word; begin

Result := CurrentYear; end;

exports

Factorial, GetCurrentYear;

begin

ShowMessage('Вас вітає динамічна бібліотека.'); end.

Підключення бібліотеки до програми

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

Створіть нову форму і помістіть на ньому дві кнопки Button, два написи Label і компонент SpinEdit (| на вкладці Samples).

Цей компонент дозволяє користувачеві вводити число як з клавіатури, так і клацаннями по стрілках «більше» і «менше». Після натиснення першої кнопки програма обчислюватиме факторіал числа, введеного в числове поле SpinEdit1, і виводити його в напис Label1, а після натиснення другої кнопки поточний рік буде виведений в напис Label2 (мал. 1).

Щоб компілятор знав, де шукати функції, що викликаються, йому потрібно це вказати. Додайте в секцію implementation заголовки цих функцій з ключовим словом external, що говорить про те, що функції реалізовані десь поза початковою кодою даного програма. За словом external повинне слідувати ім'я файлу бібліотеки:

function Factorial(Base: Integer): Double;

external 'Projectl.dll' name 'Factorial';

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

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

function GiveYear: Word;

external 'Projectl.dll' name 'GetCurrentYear';

Далі, як завжди, обробимо події натиснення на кнопку і подію форми OnCreate:

implementation {$R *.dfm}

// указуємо, що функцію Factorial потрібно шукати у файлі Projectl.d

// під ім'ям 'Factorial'

function Factorial(Base: Integer): Double;

external 'Project1.dll' name 'Factorial'; // указуємо, що функцію GiveYear потрібно шукати у файлі Project1.dll // під ім'ям 'GetCurrentYear' function GiveYear: Word;

external 'Project1.dll' name 'GetCurrentYear';

procedure TForm1.FormCreate(Sender: TObject); begin

Caption := 'Виклик бібліотечної функції'; SpinEdit1.MinValue := 0;

SpinEdit1.MaxValue := 25;

Button1.Caption := '&Факториал'; Button2.Caption := '&Поточний рік';

Label1.Caption := ' 0 ' ; Label2.Caption : = ''; end;

procedure Tform1.Button1Click(Sender: TObject); begin

Label1.Caption := FloatToStr(Factorial(SpinEditl.Value)); end;

procedure Tform1.Button2Click(Sender: TObject); begin

Label2.Caption := IntToStr(GiveYear); end;