当前位置: 首页 > news >正文

Qt--QPlugin插件

写在前面

Qt–动态链接库一文中提到,动态方式加载dll只能加载 extern "C“ 的导出函数,而无法加载类,因此可以使用Qt提供的插件来实现导出类的动态加载。

QPlugin是Qt插件框架的一部分,是一种轻量级的插件系统,用于在QT应用程序中动态加载和卸载功能模块,QPluginLoader类提供了对Qt插件的访问。

开发环境:
Qt5.15.2
Qt Creator10.0.2

自定义插件步骤

自定义插件时,要先创建一个接口,作为插件类的基类。因为插件存储在一个dll中,因此可以动态的加载。

创建一个插件包含以下几步:
①定义一个接口类(只有纯虚函数的抽象类)
②使用Q_DECLARE_INTERFACE()宏在Qt的元对象系统中注册该接口
③再定义一个插件类,必须继承自QObject类和上面创建的接口类,且需先继承QObject
④在插件类中使用Q_INTERFACE()宏在Qt的元对象系统中注册该接口
⑤使用Q_PLUGIN_METADATa()宏导出该插件
⑥使用合适的.pro文件构建该插件

这里和之前的dll的创建和使用一样,同样以两个项目进行,一个插件项目,一个使用插件项目。

创建插件

打开Qt Creator,新建空项目,Empty qmake Project。
1

命名为:MyPlugin
2
套件配置:
3

新建一个MyPluginInterface 接口类:
4
在MyPluginInterface.h中添加以下内容:

//myplugininterface.h
#ifndef MYPLUGININTERFACE_H
#define MYPLUGININTERFACE_H#define MYPLUGININTERFACE_IID "org.examples.myplugin.interface”class MyPluginInterface
{
public:virtual ~MyPluginInterface() {}     //这里需内敛实现virtual void printFromPlugin() = 0; //声明为纯虚函数};Q_DECLARE_INTERFACE(MyPluginInterface, MYPLUGININTERFACE_IID)#endif // MYPLUGININTERFACE_H

再创建插件类,继承自QObject:
5
6
添加对QMyPluginInterface的继承,元对象的接口注册和导出:

//myplugin.h
#ifndef MYPLUGIN_H
#define MYPLUGIN_H#include <QObject>
#include "MyPluginInterface.h"class MyPlugin : public QObject, MyPluginInterface
{Q_OBJECTQ_PLUGIN_METADATA(IID MYPLUGININTERFACE_IID)Q_INTERFACES(MyPluginInterface)public:explicit MyPlugin(QObject *parent = nullptr);void printFromPlugin();     //实现继承自基类的纯虚函数signals:};#endif // MYPLUGIN_H
//myplugin.cpp
#include "myplugin.h"
#include <QDebug>MyPlugin::MyPlugin(QObject *parent): QObject{parent}
{}void MyPlugin::printFromPlugin()
{qDebug() << "Print From Plugin";
}

最后修改.pro文件,构建项目:

//MyPlugin.pro
TEMPLATE = lib      #表明该项目要构建库
CONFIG += plugin    #告知qmake要创建一个插件HEADERS += \MyPluginInterface.h \myplugin.hSOURCES += \myplugin.cpp

构建会提示MyPluginInterface.h中有错误:D:\QtApplication\MyPlugin\MyPlugin\MyPluginInterface.h:15: error: Parameter type ‘MyPluginInterface’ is an abstract class
7

这里将MyPluginInterface.h从项目中移除,注意不要删除!
8

再重新构建生成即可:
9
可以在输出目录下看到dll:
10
然后提供:
①MyPluginInterface.h
②MyPlugin.dll

给其他项目使用即可。

使用插件

这里新建一个Qt控制台应用程序,来加载上面的插件并使用:
11
12
构建套件:
13
将MyPluginInterface.h拷贝到MyPluginTest.pro目录的include文件夹中,将MyPlugin.dll放到MyPluginTest项目的输出目录下:
14
15
在MyPluginTest.pro中添加包含目录:
16
在main.cpp中加载使用MyPlugin:

//main.cpp
#include <QCoreApplication>#include <QDebug>
#include <QPluginLoader>
#include "MyPluginInterface.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);//QPluginLoader loader("D:/QtApplication/MyPluginTest/build-MyPluginTest-Desktop_Qt_5_15_2_MSVC2019_64bit-Release/MyPlugin.dll");QPluginLoader loader("../MyPlugin.dll");QObject* instance = loader.instance();if (instance){MyPluginInterface* plugin = qobject_cast<MyPluginInterface*>(instance);if (plugin){plugin->printFromPlugin();}}else{qDebug() << "Instance is null";return 0;}return a.exec();
}

输出结果如下:
17

总结

使用QPluginLoader可动态加载dll,通过QPluginLoader::instance()得到插件接口类的实例,再通过多态调用对应插件类的接口实现,以此来弥补QLibrary不能动态加载使用导出类的缺陷。

后续扩展其他插件时,需添加抽象的插件接口类(MyPluginInterface)及其对应的插件类(MyPlugin)实现。

http://www.lryc.cn/news/114079.html

相关文章:

  • 公会发展计划 (GAP) 第 4 季:塑造 YGG 的成就版图
  • ExpressJS教程_编程入门自学教程_菜鸟教程-免费教程分享
  • 时序预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期记忆神经网络时间序列预测
  • HIVE优化之不需要参数优化
  • 前端 select 标签如何创建下拉菜单?
  • 基于 eclipse-temurin 构建国内时区,地区,语言的docker镜像
  • RunnerGo配置场景时接口模式该怎么选
  • 系统分享UIActivity
  • 常用抓包工具
  • 自然语言处理学习笔记(五)————切分算法
  • SQL-方法论
  • [Python从零到壹] 六十八.图像识别及经典案例篇之图像特效(毛玻璃、浮雕、油漆和模糊特效变换)
  • undefined与null的区别
  • Unity之获取用户地理位置
  • TC3XX - MCAL知识点(二十):CAN MCAL配置及代码实战(CAN/CANFD/extenen CAN)
  • QT生成Debug和Release发布版后,运行exe缺少dll问题
  • 企业进销存管理流程有哪些? 附进销存管理系统
  • RPC原理与Go RPC详解
  • JavaScript:异步编程的发展
  • 排序第二课【选择排序】直接选择排序 与 堆排序
  • 【chrome扩展开发】vue-i18n使用问题及解决方案
  • 【Vue3】localStorage读取数组并赋值的问题
  • 华为harmonyos4.0鸿蒙4.0安装谷歌服务框架Play商店,解决从服务器检索信息时出错
  • pcl 滤波
  • 前端js--旋转幻灯片
  • 解决mvn clean install遇到testng单元测试失败时打包也失败的问题
  • RISC-V基础之函数调用(二)栈与寄存器(包含实例)
  • 解析器模式(C++)
  • 电子元器件选型与实战应用—02 电容选型第1篇(8000字)
  • 试图将更改推送到 GitHub,但是远程仓库已经包含了您本地没有的工作(可能是其他人提交的修改)