A factory class to easily load generic plugins
- Load plugins based on their IID and static keys
- Supports both dynamic and static plugins
- Respects the QT_PLUGIN_PATH and other plugin-related settings
- Supports factory-like generic plugin factory for such plugins
The package is provided via qdep, as Skycoder42/QPluginFactory. To use it simply:
- Install and enable qdep (See qdep - Installing)
- Add the following to your pro file:
QDEP_DEPENDS += Skycoder42/QPluginFactory
!load(qdep):error("Failed to load qdep feature! Run 'qdep.py prfgen --qmake $$QMAKE_QMAKE' to create it.")A full example with a demo plugin can be found in the Sample folder. The following code snippet illustrates how to use the factory:
First, assume we have a plugin definition as follows:
class MyClass;
class IMyPlugin
{
public:
virtual inline ~IMyPlugin() = default;
virtual MyClass *createInstance(const QString &key) = 0;
};
#define IMyPluginIID "de.skycoder42.qpluginloader.sample.IMyPlugin"
Q_DECLARE_INTERFACE(IMyPlugin, IMyPluginIID)Next, create a plugin that implements this interface. The important parts here is to make shure that:
- The plugin extends
QObect - The plugin implements your interface with a JSON-Manifest
- You declare the interface via
Q_INTERFACES - The JSON-Manifest contains an element called
Keysthat holds an array of keys that identify the plugin
The plugin header could look like this:
class MyPluginImplementation : public QObject, public IMyPlugin
{
Q_OBJECT
Q_INTERFACES(IMyPlugin)
Q_PLUGIN_METADATA(IID IMyPluginIID FILE "MyPluginImplementation.json")
public:
//...
};And the corresponding JSON-Manifest as follows. For the example, we want the plugin to be identified by the key "stuff", but can can of course specify anything here, whatever fits your semantics best. Multiple keys are allowed as well.
{
"Keys" : [ "stuff" ]
}We can use the factory to create instances of this plugin by simply creating a generic instance. There are prepared macros that do so by creating a Q_GLOBAL_STATIC instance of the factory. But you can of course also create the instance yourself. The following code creates a QPluginFactory<IMyPlugin> instanced named loader that searches for plugins in a subfolder to the default Qt plugin folder (or a folder advertised via QT_PLUGIN_PATH) named myPlugin:
Q_GLOBAL_PLUGIN_FACTORY(IMyPlugin, "myPlugin", loader)
// ...
IMyPlugin *instance = loader->plugin("stuff");If you want to use the factory style instead, use the following:
Q_GLOBAL_PLUGIN_OBJECT_FACTORY(IMyPlugin, MyClass, "myPlugin", loader)
// ...
MyClass *instance = loader->createInstance("stuff");