Повысьте выбор плагинов - PullRequest
5 голосов
/ 26 января 2011

Я пытаюсь внедрить архитектуру плагинов в наше текущее приложение (Unix, C ++) и проверяю параметры (ожидающие утверждения) в библиотеках Boost.

Редактировать: Я ищу динамическидобавить классы во время выполнения.

Boost.Plugin

Boost.Reflection

Boost.Extension

Мне было интересно, что каждый испытывает / думает об этом идругие реализации.

Ответы [ 2 ]

4 голосов
/ 26 января 2011

Э.Мы только что использовали dlopen и dlsym вместе с парой extern "C" static функций, которые должны быть определены в dll

extern "C" static plugin* create( arg_pack* );
extern "C" static errno_t destroy( plugin* );

У менеджера плагинов ищите ".dll" или ".so"файлы и загрузить их в
map<string, pair< plugin*(*)(arg_pack*), errno_t(*)(plugin*)> >

Затем вы можете найти плагин на основе имени (строка выше) и получить его" конструктор "или" деструктор "

см. также: gmodule

1 голос
/ 26 января 2011

Вы не можете загружать классы во время выполнения, так как C ++ является скомпилированным языком, а классы не существуют во время выполнения. Объекты (экземпляры классов) делают.

Что вы можете сделать, это загрузить разделяемые библиотеки во время выполнения и заставить их создавать объекты определенного интерфейса.

Минимальная реализация плагина будет определять интерфейс вашего плагина и интерфейс фабричной функции, которая будет создавать объекты с этим интерфейсом. Вы собираетесь загрузить разделяемую библиотеку во время выполнения, найти фабричную функцию с определенным именем и вызвать фабричную функцию для создания объекта. Затем вы используете этот объект через интерфейс:

// plugin.h start
#include <memory>

struct PlugIn // interface
{
    virtual ~PlugIn() = 0;
    virtual void doSomething() = 0;
};

extern "C" {

typedef std::auto_ptr<PlugIn> PlugInFactoryFn();

// A plugin .so must export this one factory function.
std::auto_ptr<PlugIn> createPlugIn();

}
// plugin.h end

// somewhere in you application
#include "plugin.h"
#include <assert.h>
#include <dlfcn.h>

std::auto_ptr<PlugIn> loadPlugIn(char const* filename)
{
    void* so = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
    assert(so);
    void* factory_function = dlsym(so, "createPlugIn");
    assert(factory_function);
    return reinterpret_cast<PlugInFactoryFn*>(factory_function)();
}

int main()
{
    std::auto_ptr<PlugIn> a(loadPlugIn("a.so"));
    std::auto_ptr<PlugIn> b(loadPlugIn("b.so"));
    a->doSomething();
    b->doSomething();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...