How to implement a plugin system

Matthew Brush mbrush at codebrainz.ca
Tue Nov 10 02:58:27 CET 2015


On 2015-11-09 12:16 PM, Stephan Haller wrote:
> Hi @all,
>
> does someone has a URL to a good tutorial or code snippets about how to
> implement a plugin system. At best it would use Glib functions.
>
> I have my first "plugin" ready for xfdashboard. To be honest it use
> hard-coded and implemented in the main application code - not really a
> plugin. Now I try to build a plugin system around it. But I need to
> good way to start.
>
> Can anybody help me?
>

Aside from libpeas, which is probably the best solution for a program 
already using GObject, implementing a plugin system is quite easy. You 
basically have the plugins export a function (or more) and then using 
libdl/GModule you open the library/module and get a pointer to the 
function the plugin implements, then you can call that function from the 
core.

Often you can get away with only having a single exported function which 
when called will register a structure of function pointers that can be 
used to call back into the plugin from the core.

Some pseudo-code explaining it:

==========

//-- in a core header

struct pluginFuncs {
     void (*sayHello)(const char*);
     void (*endPlugin)(void);
};

typedef void (*pluginEntryPoint)(struct pluginFuncs*);

//-- in plugin
#include "theCoreHeader.h"

static void my_sayHello(const char *name) {
   printf("Hello %s\n", name);
}

static void my_sayGoodbye(void) {
   printf("Bye\n");
}

// plugin entry point, exported from the .so
void __declspec(dllexport) // or __attribute__(visibility...)
startPlugin(struct pluginFuncs *funcs) {
   funcs->sayHello = my_sayHello;
   funcs->endPlugin = my_sayGoodbye;
   // ... initialization code, etc ...
}

//-- in core loader code
#include "theCoreHeader.h"

// get address of plugin procedure from the .so
void *mod = dlopen("theplugin.so", ...);
pluginEntryPoint theStartFunc =
   (pluginEntryPoint)dlsym(mod, "startPlugin");

// start the plugin and get funcs to call back into
struct pluginFuncs funcs;
theStartFunc(&funcs);

// call into the plugin
funcs.sayHello("Bob");
funcs.endPlugin();

==========

It's also good practice to have the main program provide a library for 
plugins to link to, which exposes the public plugin symbols (and 
headers with the plugin API types/prototypes/etc).

There's some care needed when the plugins register GTypes in the usual 
fashion, as the plugins could get unloaded while the GLib type system is 
still pointing at where they used to reside in memory. I believe GModule 
has a function to make the plugins remain resident in memory.

Hope that helps, if you wanted to roll-your-own simple plugin mechanism.

Cheers,
Matthew Brush


More information about the Xfce4-dev mailing list