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
Keys
that 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");