Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost Plugin choices

I'm looking to implement a plugin architecture into our current application (Unix, C++) and have been reviewing the options (pending approval) within the Boost libraries.

Edit: I'm looking to dynamically add classes at runtime.

Boost.Plugin

Boost.Reflection

Boost.Extension

I was wondering what everyones experience/opinion is on these and other implementations.

like image 895
Ben Crowhurst Avatar asked Jan 26 '11 11:01

Ben Crowhurst


2 Answers

Eh. We just used dlopen and dlsym along with a pair of extern "C" static functions that must be defined in the dll

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

Have a plugin-manager look for ".dll" or ".so" files and load them into a
map<string, pair< plugin*(*)(arg_pack*), errno_t(*)(plugin*)> >

You can then lookup a plugin based on a name (the string above) and get it's 'constructor' or 'destructor'

see also: gmodule

like image 111
KitsuneYMG Avatar answered Nov 13 '22 13:11

KitsuneYMG


You can not load classes at run-time as C++ is a compiled language and classes do not exist at run-time. Objects (instances of classes) do.

What you can do is load shared libraries at run-time and make them create objects of a certain interface.

Minimal plug-in implementation would define the interface of your plug-in and the interface of the factory function that is going to create objects with that interface. You are going to load the shared library at run-time, find the factory function with a certain name, and call the factory function to create an object. Then you use that object though the interface:

// 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();
}
like image 2
Maxim Egorushkin Avatar answered Nov 13 '22 12:11

Maxim Egorushkin