PIP 5.5.3
Platform-Independent Primitives
Открытые типы | Открытые члены | Относящиеся к классу функции | Полный список членов класса
Класс PIPluginLoader

Загрузчик плагина. Подробнее...

#include <piplugin.h>

Открытые типы

enum  Error {
  Unknown , NoError , NoSuchFile , LibraryLoadError ,
  MissingSymbols , InvalidLoaderVersion , InvalidUserVersion
}
 Возможные ошибки загрузки плагина Подробнее...
 

Открытые члены

 PIPluginLoader (const PIString &name=PIString())
 Создает загрузчик с базовым именем файла "name" и вызывает load() если "name" не пустое
 
 ~PIPluginLoader ()
 Деструктор, выгружает библиотеку
 
bool load (const PIString &name)
 Загружает плагин с базовым именем "name". Подробнее...
 
void unload ()
 Выгружает плагин и освобождает библиотеку
 
bool isLoaded () const
 Возвращает успешно ли загружен плагин
 
Error lastError () const
 Возвращает ошибку последнего вызова load()
 
PIString lastErrorText () const
 Возвращает сообщение об ошибке последнего вызова load()
 
void setMessages (bool yes)
 Устанавливает должен ли PIPluginLoader выводить сообщения, true по умолчанию
 
bool isMessages () const
 Возвращает должен ли PIPluginLoader выводить сообщения, true по умолчанию
 
PIString libPath ()
 Возвращает путь к загруженной библиотеке
 
void * resolve (const char *name)
 Получает экспортированный метод библиотеки с именем "symbol". Подробнее...
 
void mergeStatic ()
 Вызывает у плагина PIP_PLUGIN_STATIC_SECTION_MERGE.
 

Относящиеся к классу функции

(не члены класса)

#define PIP_PLUGIN
 Объявляет плагин, должен быть использован перед любыми другими PIP_PLUGIN_* макросами
 
#define PIP_PLUGIN_SET_USER_VERSION(version)
 Устанавливает пользовательскую версию для проверки во время загрузки, "version" - строка в кавычках
 
#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr)
 Добавляет указатель для будущего слияния. Тип - целое число
 
#define PIP_PLUGIN_STATIC_SECTION_MERGE
 Объявляет метод для слияния статических секций Подробнее...
 
#define PIP_PLUGIN_EXPORT
 Пометить метод на экспорт
 

Подробное описание

Загрузчик плагина.

Краткий обзор

Этот файл предоставляет несколько макросов для объявления плагина и PIPluginLoader - класс для его загрузки и проверки.

Сторона плагина

Плагин - это разделяемая библиотека, которая может быть загружена динамически. Необходимым является только макрос PIP_PLUGIN. Можно установить версию для дополнительной проверки с помощью макроса PIP_PLUGIN_SET_USER_VERSION(version). Также можно объявить метод для слияния статических секций между приложением и плагином с помощью макроса PIP_PLUGIN_STATIC_SECTION_MERGE. Перед слиянием необходимо установить указатели для секций с помощью макроса PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr).

Сторона приложения

Приложение должно использовать класс PIPluginLoader для загрузки плагина. Основной метод - это load(PIString name). "name" является базовым именем для поиска библиотеки. PIPluginLoader попробует несколько имен, <name>, lib<name> и расширения "dll", "so" и "dylib", в зависимости от системы.
Например:

l.load("foo");
Загрузчик плагина.
Definition: piplugin.h:159
bool load(const PIString &name)
Загружает плагин с базовым именем "name".
Definition: piplugin.cpp:327

На Windows будут опробованы "foo", "libfoo", "foo.dll" и "libfoo.dll".
Если нужна проверка пользовательской версии, установите ей с помощью макроса PIP_PLUGIN_SET_USER_VERSION(version). Когда плагин будет успешно загружен и проверен, можно будет получать из него свои методы с помощью resolve(name), аналогично PILibrary.

Заметки
Необходимо использовать PIP_PLUGIN_EXPORT и C-linkage для методов, получаемых через resolve(name)!

Статические секции

Макрос PIP_PLUGIN_STATIC_SECTION_MERGE объявляет метод с аргументами (int type, void * from, void * to), поэтому можно оставить его как объявление, или реализовать тут же:

switch (type) {
...
}
}
#define PIP_PLUGIN_STATIC_SECTION_MERGE
Объявляет метод для слияния статических секций
Definition: piplugin.h:70
Заметки
При использовании синглтонов надо помнить, что реализованные в cpp синглтоны в разделяемых библиотеках едины для всего приложения, включая плагины! Однако реализованные в h-файлах синглтоны, либо из статических библиотек, не являются реальными одиночками, и для каждого плагина и приложения будет свой объект. В этом случае можно провести слияние статических секций.

В любом случае, если используется макрос PIP_PLUGIN_STATIC_SECTION_MERGE, то он вызывается первый раз во время загрузки плагина с "from" - областью плагина, "to" - областью приложения, и второй раз (необязательно) при вызове mergeStatic() с "from" - областью приложения и "to" - областью плагина.
Первый вызов позволяет скопировать статические секции из плагина в приложение, второй - из приложения (и всех остальных плагинов) в плагин.

Примеры

Простой плагин:

#include <piplugin.h>
extern "C" {
PIP_PLUGIN_EXPORT void myFunc() {
piCout << "Hello plugin!";
}
}
#define PIP_PLUGIN_EXPORT
Пометить метод на экспорт
Definition: piplugin.h:75
#define PIP_PLUGIN
Объявляет плагин, должен быть использован перед любыми другими PIP_PLUGIN_* макросами
Definition: piplugin.h:40
#define piCout
Макрос для условного (piDebug) вывода в PICout(StdOut)
Definition: picout.h:35
Управление плагинами

Приложение:

#include <piplugin.h>
int main() {
pl.load("your_lib");
if (pl.isLoaded()) {
typedef void(*MyFunc)();
MyFunc f = (MyFunc)pl.resolve("myFunc");
if (f) f();
}
return 0;
}
void * resolve(const char *name)
Получает экспортированный метод библиотеки с именем "symbol".
Definition: piplugin.cpp:430
bool isLoaded() const
Возвращает успешно ли загружен плагин
Definition: piplugin.cpp:400

Сложный плагин:

#include <piplugin.h>
PIStringList global_list;
global_list << "plugin_init";
PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to;
*sto << *sfrom;
}
#define PIP_PLUGIN_SET_USER_VERSION(version)
Устанавливает пользовательскую версию для проверки во время загрузки, "version" - строка в кавычках
Definition: piplugin.h:45
#define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr)
Добавляет указатель для будущего слияния. Тип - целое число
Definition: piplugin.h:50
Основанный на PIDeque<PIString> массив строк.
Definition: pistringlist.h:36
PIStringList & removeDuplicates()
Удаляет все дублированные строки и возвращает ссылку на этот список строк
Definition: pistringlist.cpp:75
#define STATIC_INITIALIZER_BEGIN
Макрос для начала статической инициализации
Definition: pibase_macros.h:374
#define STATIC_INITIALIZER_END
Макрос для окончания статической инициализации
Definition: pibase_macros.h:379

Приложение:

#include <piplugin.h>
PIStringList global_list;
int main() {
global_list << "app";
pl.load("your_lib");
piCout << "list =" << global_list;
return 0;
}
void mergeStatic()
Вызывает у плагина PIP_PLUGIN_STATIC_SECTION_MERGE.
Definition: piplugin.cpp:443

Перечисления

◆ Error

Возможные ошибки загрузки плагина

Элементы перечислений
Unknown 

Не было вызова load()

NoError 

Нет ошибки

NoSuchFile 

Не найден файл библиотеки

LibraryLoadError 

Система не смогла загрузить библиотеку

MissingSymbols 

Нет необходимых методов

InvalidLoaderVersion 

Неверная внутренняя версия

InvalidUserVersion 

Неверная пользовательская версия

Методы

◆ load()

bool PIPluginLoader::load ( const PIString name)

Загружает плагин с базовым именем "name".

Загрузчик пробует приставку "lib" и окончания ".dll", ".so" или ".dylib", в зависимости от системы

◆ resolve()

void * PIPluginLoader::resolve ( const char *  name)

Получает экспортированный метод библиотеки с именем "symbol".

См. также
PILibrary::resolve()

Документация по друзьям класса и функциям, относящимся к классу

◆ PIP_PLUGIN_STATIC_SECTION_MERGE

#define PIP_PLUGIN_STATIC_SECTION_MERGE
related

Объявляет метод для слияния статических секций

Этот метод имеет 3 аргумента: (int type, void * from, void * to). Он вызывается первый раз при загрузке плагина с "from" - областью плагина, "to" - областью приложения, и второй раз (необязательно) при вызове PIPluginLoader::mergeStatic() с "from" - областью приложения и "to" - областью плагина. Таким образом, этот макрос позволяет провести слияние статических данных приложения и плагина.