Створення простої програми з плагінами - все про IT та програмування
Written on 04 Лютого 2007 . Posted in Visual C++
Модульи, що динамічно підключаються (DLL) - це модулі, які містять функції і дані. Ці модулі завантажуються під час виконання програми, яка використовує ці модулі (хоста). У Windows модулі містять внутрішні та експортовані функції (у UNIX подібних системах всі функції експортуються). Функції, що експортуються, доступні для виклику хостом, а внутрішні ні. Хоча дані також можуть бути експортованими, але зазвичай використовуються функції експортування для доступу даним.
Деякі, особливо початківці розробники ПЗ, і не уявляють, що при створенні програми вже використовують зовнішні модулі. Хоча при розробці MFC додатків цей факт є більш очевидним. Просто компілятор сам вставляє код, який завантажує системні бібліотеки, інакше будь-яка програма Windows була б на 20-30 Мб більше.
Отже, перейдемо безпосередньо до створення механізму для використання у ваших додатках плагінів.
Створіть нову DLL програму (Builder та VC дозволяють вибрати тип при створенні нового проекту).
Кожна бібліотека має точку входу (але можна її не описувати), як функція main() у звичайному додатку. Ось звичайний її опис:
При приєднанні до процесу, що викликав її, в цю функцію передається instance. Тобто. Ви зможете використати ресурси бібліотеки. Використовуйте у цій функції лише прості завдання з ініціалізації! Ця функція дуже вразливе місце у модулі.
Для зв'язку хоста та модуля пропоную використовувати дві функції: перша функція буде взаємодіяти з хостом під час ініціалізації (визначати версію, сумісність із поточною версією хоста, передавати текст для пункту в меню тощо), а друга обслуговуватиме запитихоста та реагувати на передані дані: аналізувати, обробляти та повертати результат соєю роботи.
Інший підхід у написанні плагінів - використовувати кілька різних функцій для кожної з дій, але особисто мені подобається перший.
Наприклад, один із можливих варіантів цих двох функцій:
Ключові слова __declspec( dllexport ) позначають, що функції експортуються.
Цей блок визначень можна поміщати у вихідному файлі, після секції підключення заголовних файлів.
Ось приклад структури, що передається під час ініціалізації:
А ось приклад функції, яка знаходиться у плагіні та заповнює цю структуру:
Функція-обробник у плагіні:
Перший параметр визначатиме мету, з якою викликана функція, другий параметр визначає вхідні дані, причому кожного коду можуть бути ініціалізовані різні члени структури. Ну а третій параметр – результат роботи.
Якщо плагін не знає переданого коду операції, він поверне код "Не підтримується" і не виконає некоректних дій.
Подивимося, які дії необхідно виконати в програмі-хості для того, щоб скористатися функціями, розміщеними в плагінах.
Завантажимо бібліотеку хостом:
Отже, плагін завантажений і готовий до роботи, очікуємо, коли користувач вибере пункт меню.
Поміщаємо в обробник меню наступний код:
Ось, власне, і весь опис простого прикладу використання плагінів у своїх програмах.
Я хочу додати кілька порад для розробників:
- якщо планується використовувати багато плагінів, то розумно спочатку отримати початкову інформацію від плагіну, а потім його вивантажити з пам'яті. І підвантажувати його у разі потреби.
- якщо користувачвводить деякі параметри в діалогах плагінів, розумно розробити механізм централізованого зберігання останніх введених параметрів.
- робіть можливість розміщення плагінів у довільних папках усередині папки плагінів. Код рекурсивного пошуку плагінів наведено нижче.
- Задайте своїм плагінам відмінне від "dll" розширення. Т.к. Самі плагіни можуть використовувати зовнішні бібліотеки DLL.
А ось приклад функції, яка рекурсивно знаходить усі файли в папці з плагінами: