У дружини програміста запитали:
- А як він за тобою доглядав?
Дружина, після хвилинного роздуму:
- Ну-у, комп'ютер показав.
Області застосування 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. Це також необов'язкова директива.
2 спосіб. Динамічне завантаження DLL
Це набагато більш складний, але і більш елегантний метод. Він позбавлений недоліку першого методу. Єдине, що неприємно - об'єм коду, необхідного для здійснення цього прийому, причому складність в тому, що функція, імпортована з DLL достуна лише тоді, коли ця DLL завантажена і знаходиться в пам'яті. З прикладом можна ознайомитися нижче, а поки - короткий опис використовуваних цим методом функцій WinAPI:
LoadLibrary (LibFileName: PChar) завантаження зазначеної бібліотеки LibFileName в пам'ять. При успішному завершенні функція повертає дескриптор (THandle) DLL в пам'яті. GetProcAddress (Module: THandle; ProcName: PChar) зчитує адpес експоpтіpованной бібліотечної функції. При успішному завершенні функція повертає дескриптор (TFarProc) функції в завантаженої DLL. FreeLibrary (LibModule: THandle) робить недійсним LibModule і звільняє пов'язану з ним пам'ять. Слід зауважити, що після виклику цієї процедури функції даної бібліотеки більше недоступні.
Практика і приклади
Ну а тепер пора привести пару прикладів використання перерахованих вище методів і прийомів:
Приклад 1. Прив'язка DLL до програми