Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plugin API design

Tags:

c++

plugins

dll

qt

api

So I have an application that is based heavily on the QT API which using the QPlugin system. It's fairly simple to use, you define a class which inherit from an Interface and when the plugin is loaded you get an instance of that class. In the end it'll boil down to a dlopen/dlsym or LoadLibrary/GetProcAddress, whatever is appropriate for the OS. I have no problems here everything works as expected.

So, onto the issue. There is a lot of functionality that involves a plugin needing to refer to data/functions provided by the main application. For example, my application has a GUI, so I have in my application a "plugin::v1::gui" function which returns a QWidget *. If I want a plugin to be able to add things to my UI, or even make it's dialog a child of my UI it'll need a pointer to it.

I started development on Linux and quickly encountered the fact that by default the loader doesn't fill in unresolved symbols in shared objects with the ones from the application loading it. No problem, easy fix. add "-rdynamic" to my flags and move on. Thing work well.

Now I've discovered that there doesn't appear to be an equivalent on Windows :(. So what is a good solution?

So far the best I've come up with is having a structure I fill up in my main application that has pointers to every object/function a plugin might care about. Then passing that to the plugin's "init()" function and now it has proper pointers to everything, but it's an annoying solution since now I have to make changes in multiple places whenever I add something.

Is there a better solution? How has the SO community dealt with this?

like image 766
Evan Teran Avatar asked Dec 09 '08 01:12

Evan Teran


1 Answers

Create a set of interfaces for the main interaction objects that will be exposed by your application and build them in a lib/dll of their own and implement those interfaces on classes in your application as appropriate. The library should also include a plugin interface with perhaps just an "initialize" method that the plugin object will implement.

The application and plugin will obviously link against that DLL and once the plugin is loaded by the application the application should call the plugin's initialize method which will have parameters to accept any objects needed to control the application.

A popular way of making this simple is to implement a hierarchy similar to the DOM in your application so that the plugin can get to all the relevant objects in your application from one root object.

like image 88
joshperry Avatar answered Sep 27 '22 16:09

joshperry