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