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

【Qt】QPluginLoader 类学习

文章目录

  • 一、简介
  • 二、常用方法
    • 2.1 构造函数
    • 2.2 动态加载方法——load()
    • 2.3 检查是否加载成功——isLoaded()
    • 2.4 访问插件中的根组件——instance()
    • 2.5 卸载插件——unload()

一、简介

QPluginLoader 类在运行时加载插件。

QPluginLoader 提供对Qt插件的访问。Qt插件存储在共享库(如 DLL 文件)中,相比于 QLibrary访问的共享库, QPluginLoader 具有以下优点:

  • QPluginLoader 会检查插件是否与应用程序使用的Qt版本一致;
  • QPluginLoader 提供对根组件对象 (instance())的直接访问,而无需动手解析C函数

QPluginLoader 对象的实例操作单个共享库文件,这个共享库文件被称为插件。它以独立于平台的方式提供对插件中功能的访问。要指定要加载的插件,请在构造函数中传递文件名,或者使用setFileName()方法进行设置。

使用 QPluginLoader 类一旦加载成功,插件会保留在内存中,直到所有 QPluginLoader 实例都被卸载,或者直到应用程序终止。可以使用多个unload()卸载插件,但如果其它 QPluginLoader 实例仍在使用相同的库,则调用将失败,卸载仅在所有实例都调用了unload()后才会发生。在卸载之前,根组件也将被删除。

注意:
请注意,如果您的应用程序是静态链接 Qt 的,则不能使用 QPluginLoader。在这种情况下,您还需要静态链接插件。如果需要在静态链接的应用程序中加载动态库,可以使用 QLibrary

二、常用方法

2.1 构造函数

原型:

QPluginLoader::QPluginLoader(const QString &fileName, QObject *parent = Q_NULLPTR)

解释:
使用给定的父级构造一个插件加载器,该加载器将加载fileName指定的插件。

为了可加载,文件的后缀必须是符合平台的可加载库的有效后缀,例如Unix上的.so,macOS和iOS上的.dylib,以及Windows上的.dll。后缀可以通过QLibrary::isLibrary()进行验证。

注:parent是可选的。

2.2 动态加载方法——load()

原型:

bool QPluginLoader::load()

解释:
作用:动态加载插件。
如果插件加载成功,则返回true,否则返回false。由于instance()总是在解析任何符号之前调用此函数,因此没有必要显示地调用它。在某些情况下,我们可能希望提前加载插件,此时则可以使用该方法。

2.3 检查是否加载成功——isLoaded()

原型:

bool QPluginLoader::isLoaded() const

解释:

如果插件已加载,则返回true,否则返回false

2.4 访问插件中的根组件——instance()

原型:

QObject *QPluginLoader::instance()

解释:

返回插件的根组件对象,必要时加载插件。如果无法加载插件或无法实例化根组件对象,则函数返回 0 。

如果根组件被销毁,调用此函数将创建一个新实例。
QPluginLoader被销毁时,此函数返回的根组件不会被删除。如果你想确保根组件被删除,你应该在不需要再访问核心组件是调用unload()。当库最终卸载时,根组件将自动删除。

组件对象时QObject。使用qobject_cast()访问你感兴趣的接口。

2.5 卸载插件——unload()

原型:

bool QPluginLoader::load()

解释:

如果可以卸载插件,则卸载插件并返回true;否则返回false

在应用程序终止时,会自动卸载插件,因此通常不需要调用此函数。

如果 QPluginLoader 的其它实例正在使用相同的插件,则调用将失败,并且只有在每个实例都调用了unload()时才会进行卸载。

注: 不要手动删除根组件对象,而是依赖于unload()方法来自动删除它。因为手动删除根组件对象可能会引起内存管理问题,比如访问已删除对象的错误或资源泄露。

错误举例 (手动删除根组件,会导致未定义行为):

#include <QPluginLoader>
#include <QObject>class MyPluginComponent : public QObject {Q_OBJECT
public:MyPluginComponent() {}~MyPluginComponent() {}void doSomething() {}
};int main() {QPluginLoader loader("MyPlugin.dll");QObject *rootComponent = loader.instance();if (rootComponent) {// 错误的手动删除根组件delete rootComponent; // 这里手动删除了根组件对象// 尝试再次使用 rootComponent,会导致未定义行为MyPluginComponent *myComponent = qobject_cast<MyPluginComponent *>(rootComponent);if (myComponent) {myComponent->doSomething(); // 这里会访问已被删除的对象,导致崩溃或未定义行为}}// 即使调用 unload(),根组件已经被手动删除,可能会导致内存错误loader.unload(); // 此时 unload() 不能正确处理已删除的对象return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【社区团购技术实现】
  • 【问题】容器部署场景Spring Bean偶尔循环依赖问题
  • 71、docker网络
  • 白骑士的Matlab教学高级篇 3.1 高级编程技术
  • 聊聊场景及场景测试
  • [Meachines] [Medium] Haircut Curl命令注入+TRP00F自动化权限提升+Screen4.5.0权限提升
  • C语言类型转换的问题
  • 数据结构----队列
  • RabbitMq消息队列(缓存加速)
  • 登录过程记录
  • 讲解 狼人杀中的买单双是什么意思
  • php 在app中唤起微信app进行支付,并处理回调通知
  • mysql误删数据恢复记录
  • 判断 I2C 总线通信异常原因的方法2
  • HarmonyOS WebView
  • Mysql5.6主从复制
  • Next.js之基础概念(二)
  • nginx 配置多 域名 + 多 https
  • overflow: hidden IE7无效
  • 从0实现一个tiny react(三)生命周期
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 嵌入式文件系统
  • 如何胜任知名企业的商业数据分析师?
  • 小程序button引导用户授权
  • 用jQuery怎么做到前后端分离
  • 怎么将电脑中的声音录制成WAV格式
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • AI算硅基生命吗,为什么?
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • #define 用法
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (七)Activiti-modeler中文支持
  • (三)Kafka离线安装 - ZooKeeper开机自启
  • (五)c52学习之旅-静态数码管
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .net core Redis 使用有序集合实现延迟队列
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .Net的C#语言取月份数值对应的MonthName值
  • /dev下添加设备节点的方法步骤(通过device_create)
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [1127]图形打印 sdutOJ
  • [20150707]外部表与rowid.txt
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [2019/05/17]解决springboot测试List接口时JSON传参异常
  • [AIGC] MySQL存储引擎详解
  • [AIGC] SpringBoot的自动配置解析
  • [bzoj 3534][Sdoi2014] 重建
  • [BZOJ] 3262: 陌上花开