Створення простої програми з плагінами - все про 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.

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