How to implement a plugin system

Stephan Haller nomad at froevel.de
Wed Nov 11 11:42:41 CET 2015


Hi,

thanks to you and André for your help and suggestions. It helped a lot.

As you already guessed I wanted to roll-out-my-own plugin system because 
I want to learn how to do it in the first place. The other thing is that 
I want to try to keep the number of dependencies low - at least now ;)

Although I do not use libpeas it directed me into the right way. I now 
have a simple and dirty plugin manager and a working plugin registering 
a new view to xfdashboard which is simply showing a clock :D Now I have 
to clean up code and make it more robust and using it more convinient.

Yeah, plugins are coming - finally. I'm excited ;)

Thanks
Stephan

Am 10.11.2015 02:58, schrieb Matthew Brush:
> 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
> _______________________________________________
> Xfce4-dev mailing list
> Xfce4-dev at xfce.org
> https://mail.xfce.org/mailman/listinfo/xfce4-dev


More information about the Xfce4-dev mailing list