Qt的面向接口编程和运行时动态加载

一、让应用程序支持插件,使其可以扩展。

为了让你的主程序能够加载和使用插件,你需要:

(1)定义接口:创建一个只有纯虚函数的基类,作为与插件通信的"协议"或"契约"。

(2)声明接口:使用Q_DECLARE_INTERFACE(InterfaceClassName,"唯一的标识字符串")宏,将该接口注册到Qt的元对象系统中。

(3)加载插件:在应用程序中使用QPluginLoader类来动态发现和加载插件库(如.dll .so文件)

(4)验证与转换:加载后,使用qobject_cast<InterfaceClassName*>(pluginInstance)来检查插件是否实现了所需接口,并安全地获取接口指针。

二、编写一个具体的插件

要创建一个实现上述接口的插件,你需要:

(1)声明插件类:创建一个类,它同时继承自QObject和你想要实现的接口;

(2)注册接口:在类声明的private区域使用Q_INTERFACE(InterfaceClassName)宏,告知Qt这个类实现了哪些接口。

(3)导出插件:使用Q_PLUGIN_METADATA(IID "唯一标识" FILE "元数据文件")宏来导出插件,并提供唯一标识符和可选的元数据文件。

(4)构建插件:在项目文件(.pro)中,使用TEMPLATE = lib和CONFIG += plugin等配置,将项目编译为插件库,而不是独立应用程序。

总结:这套机制的本质是"面向接口编程"和"运行时动态加载"。即主程序只依赖一个稳定的接口,不关心具体实现;插件负责实现这个接口,并打包成动态库;Qt的元对象系统和插件加载器在运行时将两者连接起来。主程序通过约定的"唯一标识符IID"找到并加载正确的插件,然后通过接口调用其功能;这样做使得你可以独立开发和更新插件,而不需要重新编译主应用程序,极大的增强了软件的模块化和可扩展性。

三、qobject_cast<>

(1)在应用程序中使用qobject_cast<>不仅仅是简单的C++强制类型转换,更是它能安全地检查接口实现。在C++中,static_cast在编译时期检查,属于静态类型信息,不运行时检查;dynamic_cast运行时检查,需要RTTI,依赖C++虚表,通常在Qt中不可用;qobject_cast运行时检查,使用Qt的元对象系统。

(2)qobject_cast<>的工作原理:使用的前提条件具有Qt的元对象系统,继承QObject并且有Q_OBJECT宏,这样做之后,Qt的MOC(元对象编译器)会为这个类生成额外的代码;创建一个静态QMetaObject对象,其中包含:类名、父类信息、信号/槽信息、实现的接口列表,在插件式开发中,检查这个类实现的接口列表,再和目标接口的IID进行比对,如果实现了目标接口才能进行转换,否则返回空指针。

(3)完整的工作原理。

相关推荐
慧都小项2 天前
当边缘AI上产线:QtitanDocking 如何让工业 HMI 实现多视图协同
人工智能·qt·ui·边缘计算·qt6.3
Quz2 天前
QML SwipeDelegate 滑动委托
qt
Quz2 天前
QML 列表中的四种委托:ItemDelegate、CheckDelegate、RadioDelegate、SwitchDelegate
qt
实心儿儿2 天前
Qt — 显示类控件
qt
江湖人称菠萝包3 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter9-Qt Charts
笔记·qt·qt5
扶尔魔ocy3 天前
【QT android】环境安装及第一个QT项目
qt·andriod开发
江湖人称菠萝包3 天前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter10-Data Visualization
笔记·qt·qt5
Cx330❀3 天前
Qt 常用控件属性与底层机制详解:从窗口半透明、浮点数陷阱到 QSS 与焦点策略
qt·ui·图形渲染
Quz3 天前
QML DelegateChooser:多条件组合与按列选择委托
qt
Quz3 天前
QML DelegateChooser:按角色选择委托与按索引选择委托
qt