1, an overview of the

Why should we learn about plugins, and how is it different from exporting DLLS for Windows?

  1. If the exported dynamic library is missing, the program will not run. But plug-ins do.
  2. The same set of code, you can generate plug-ins under Windows and Linux respectively.

QT itself provides two types of plug-in support, one called the high-level API and one called the low-level API.

  1. The advanced API is used to extend the QT program itself, which requires subclassing the plug-in base classes provided by QT, such as the existing QTSqlDriver, so you can also extend QT by writing your own QTStyle.
  2. The low-level API is used to extend your program in the form of a dynamic library, or DLL in Windows. At the same time, because high-level apis are built on low-level apis, it is not difficult to master low-level API usage without high-level API usage.

The QPluginloader class is used to load QT plugins. You can write plugins that support any function. How to create a plug-in and load the plug-in is described in QT Assist:

To create a plug-in that extends the application:

  1. Defines a set of interfaces (classes with only pure virtual functions) for talking to the plug-in. (Ports are reserved to facilitate communication).
  2. The Q_DECLARE_INTERFACE() macro is used inside the interface to tell qt’s meta-object system about the interface.
  3. Use QPluginLoader to load the plug-in.
  4. Qobject_cast is used to verify that the plug-in implements the specified interface (in case of external plug-in injection), and the transformation succeeds to get the plug-in instance.

Specific steps for plug-in writing (code writing) :

  1. Declare the plug-in class and inherit from QObject and implement the established interface mentioned above.
  2. Use Q_INTERFACES to tell the QT meta object system about this interface (virtual methods).
  3. Export the plug-in using Q_PLUGIN_METADATA. (Q_PLUGIN_METADATA is a macro for QT5, QT4 uses Q_EXPORT_PLUGIN2)
  4. Write appropriate.pro files.

2, the instance,

Create a subdirectory named PluginApp

Create a new QWidget project under PluginApp named Main

3. Right-click your PluginApp and create a new subproject

4. Project directory structure

Create a new header file interfaceplugin.h under Main

Interfaceplugin. h #ifndef INTERFACEPLUGIN_H #define INTERFACEPLUGIN_H #include <QString> #include <QtPlugin class InterfacePlugin { public: virtual ~InterfacePlugin() {} virtual QString output(const QString &message) = 0; }; # define InterfacePlugin_iid Test. The Plugin. "InterfacePlugin" / / unique identifier Q_DECLARE_INTERFACE (InterfacePlugin, InterfacePlugin_iid) #endifCopy the code

Load plug-ins

#main.cpp #include "widget.h" #include <QApplication> #include <QDir> #include <QPluginLoader> #include "interfaceplugin.h" #include <QObject> #include <QDebug> int main(int argc, char *argv[]) { QApplication a(argc, argv); // Widget w; // w.show(); QDir path = QDir(qApp->applicationDirPath()); path.cd(".. /plugins"); foreach (QFileInfo info, path.entryInfoList(QDir::Files | QDir::NoDotAndDotDot)) { QPluginLoader pluginLoader(info.absoluteFilePath()); QObject *plugin = pluginLoader.instance(); if (plugin) { InterfacePlugin *app = qobject_cast<InterfacePlugin*>(plugin); if (app) { app->output("i am a plugin"); } } } return a.exec(); }Copy the code

Seven, write plug-in. Pro file, header file, CPP file

# plugin. pro TEMPLATE = lib # makefile CONFIG += plugin # TARGET = pluginA # DESTDIR = . HEADERS += \ plugina.h SOURCES += \ plugina.cpp DISTFILES += \ programmerCopy the code
#this is pluginA.h #ifndef PLUGINA_H #define PLUGINA_H #include <QObject> #include <QtPlugin> #include ".. /Main/interfaceplugin.h" class PluginA : public QObject, Public InterfacePlugin {// Programmer. Json Q_OBJECT Q_PLUGIN_METADATA(IID InterfacePlugin_iid FILE // QT5.0 introduces Q_INTERFACES(InterfacePlugin) public: explicit PluginA(QObject *parent = 0); virtual QString output(const QString &message) Q_DECL_OVERRIDE; }; #endif // PLUGINA_HCopy the code

Json “programmer. Json “is a plug-in description file that is loaded into the plug-in as metadata and can be read manually if needed. It contains the basic information about the plug-in and, more importantly, the dependencies of the plug-in, which determine the order in which the plug-in is loaded.

{" author ":" QHT ", "date" : "2019/05/27", "name" : "pluginA", "version" : "1.0.0", "des" : "Dependencies" : []}Copy the code
#this is pluginA.cpp #include "pluginA.h" #include <QtDebug> PluginA::PluginA(QObject *parent) : QObject(parent) {} QString PluginA::output(const QString &message) {qDebug() << message + "PluginA loaded successfully "; return message; }Copy the code

Eight, run,

Note: 1. The Main project chose the QWidget GUI project for a reason, which will be explained in the next section. 2. The plug-in generated in Windows is the DLL suffix, and the plug-in generated in Linux is the so suffix (the next part is the Linux test results).

The Demo address: download.csdn.net/download/u0… Github.com/qht10030778…