This is the 29th day of my participation in the August Wenwen Challenge.More challenges in August

1, an overview of the

Why do we want to learn about plug-ins, and what is the difference between them and Windows export DLLS?

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

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

  1. The advanced API is used to extend the QT application itself. You need to subclass the plug-in base classes provided by QT, such as the existing QTSqlDriver, so you can also write your own QTStyle extensions to QT.
  2. The low-level API is used to extend its own program, which is in the form of a dynamic library, which is a DLL under Windows. And because the high-level API is based on the low-level API, it is not difficult to master the low-level API usage and the high-level API usage.

QT plugins need to be loaded using the QPluginloader class. You can write plugins that support any function. How to create a plug-in and load it is described in QT Assist like this:

Create a plug-in that extends the application:

  1. Define a set of interfaces (classes with pure virtual functions only) for talking to plug-ins. (Reserved good interface, easy to establish 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. Use qobject_cast to verify that the plug-in implements the specified interface (in case of external plug-in injection), and the conversion succeeds to get the plug-in instance.

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

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

2, the instance,

Create a new subdirectory project PluginApp

2. Create a new QWidget project named Main under PluginApp

3. Right-click PluginApp and create a new subproject called pluginA

4. Project directory structure

Create a header file interfaceplugin.h under Main

#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 the plug-in

#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

7. Write plug-in. Pro files, header files and CPP files

#pluginA. Pro TEMPLATE = lib # indicates that this makefile is a lib makefile CONFIG += plugin # TARGET = pluginA # generated the name of the plugin DESTDIR = . HEADERS += \ plugina.h SOURCES += \ plugina.cpp DISTFILES += \ plugina.json #Copy the code
#this is pluginA.h #ifndef PLUGINA_H #define PLUGINA_H #include <QObject> #include <QtPlugin> #include ".. /Main/interfaceplugin.h" class PluginA : public QObject, Json information description class Q_OBJECT Q_PLUGIN_METADATA(IID InterfacePlugin_iid FILE Json ") // QT5.0 introduce Q_INTERFACES(InterfacePlugin) public: explicit PluginA(QObject *parent = 0); virtual QString output(const QString &message) Q_DECL_OVERRIDE; }; #endif // PLUGINA_HCopy the code

“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 basic information about plug-ins and, more importantly, dependencies of plug-ins, which determine the order in which plug-ins are loaded. We’ll talk about dependencies in the next article.

{" author ":" QHT ", "date" : "2019/05/27", "name" : "pluginA", "version" : "1.0.0", "des" : < span style = "max-width: 100%; clear: both; min-height: 1em;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 + "plug-in A loading success "; return message; }Copy the code

Eight, run,

Note: 1. The QWidget GUI project was chosen for a reason in the Main project, which will be explained next. 2. Plug-ins generated under Windows are DLL suffixes, while those generated under Linux are.so suffixes (see the Linux test results in the next article).

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