| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> QT插件加载与相关宏定义 -> 正文阅读 |
|
[C++知识库]QT插件加载与相关宏定义 |
1.?应用程序与插件加载对于QT应用程序来讲,一个插件就是一个类的实例。插件的可用的方法由对应的接口类来决定。接口类仅仅包含纯虚函数,也就是说接口并不实现任何方法函数。插件通过继承QObject且继承对应的接口类来实现内部的具体函数功能。当应用程序用QPLuginLoader类加载可能的插件时,就会得到一个指向QObject的指针。通过将这个对象用qobject_cast 强制封装成接口类,应用程序就会分辨出插件是否真正实现了期望的接口,如果是就被加载成正确的插件。 要让QPluginLoader正确工作需要两个条件:1.插件接口类需要用宏Q_DECLARE_INTERFACE来声明;2.插件类本身也需要用Q_INTERFACES宏来声明表示实现了接口。这两个宏能够安全地让插件类与插件接口类匹配。事实上,QT在加载插件时有一个如下的检测标准,如果不满足,插件就不能正确加载。检查标准列表:
比如,我们已经定义了AddInInterfaceBase接口类,可以如下声明接口类, Q_DECLARE_INTERFACE(AddInInterfaceBase, AddInInterface_CurrentVersion) 该宏定义在qobject.h中,其实就是定义了3个模板内联函数,展开如下, # define Q_DECLARE_INTERFACE(IFace, IId) \ ??? template <> inline const char *qobject_interface_iid<IFace *>() \ ??? { return IId; } \ ??? template <> inline IFace *qobject_cast<IFace *>(QObject *object) \ ??? { return reinterpret_cast<IFace *>((object ? object->qt_metacast(IId) : nullptr)); } \ ??? template <> inline IFace *qobject_cast<IFace *>(const QObject *object) \ ??? { return reinterpret_cast<IFace *>((object ? const_cast<QObject *>(object)->qt_metacast(IId) : nullptr)); } #endif 2.Q_INTERFACES插件实现接口声明 Q_INTERFACE宏定义在qobjectdef.h中 #define Q_INTERFACES(x) QT_ANNOTATE_CLASS(qt_interfaces, x) 进一步解析QT_ANNOTATE_CLASS,找到如下宏定义, #ifndef QT_ANNOTATE_CLASS # ifndef Q_COMPILER_VARIADIC_MACROS #? define QT_ANNOTATE_CLASS(type, x) # else #? define QT_ANNOTATE_CLASS(type, ...) # endif #endif 这里可以看到只是一个空的定义,所以在源码中没有实际意义。主要用于MOC的输入,MOC会为Q_INTERFACES动态生成一些代码,确保qobject_cast()能正确进行QObject*到接口指针的转换,下面实例中详细讲述。 3. Q_PLUGIN_METADATA插件元数据宏 #define Q_PLUGIN_METADATA(x) QT_ANNOTATE_CLASS(qt_plugin_metadata, x) 与Q_INTERFACES类似,在代码层面也是空的,也用于MOC的输入,让MOC来动态生成一些代码。实际上,Q_PLUGIN_METADATA让MOC生成导出函数qt_plugin_instance(),供QPluginLoader()调用,创建接口实例,返回QObject的指针,在下面实例中详述。 4.MOC与Q_INTERFACES\Q_PLUG_METADATA的关系 Qt的插件机制是建立在元对象系统之上,所以要看一下Moc与Q_INTERFACES\Q_PLUGIN_METADATA两个宏之间的关系。 以OpenCVGrabber插件为例, ? Q_PLUGIN_METADATA宏在自动生成的Moc文件中有IID与ClassName的信息,如下图, ? 查看一下,QT_MOC_EXPORT_PLUGIN的宏定义, # define QT_MOC_EXPORT_PLUGIN(PLUGINCLASS, PLUGINCLASSNAME) \ ??????????? Q_EXTERN_C Q_DECL_EXPORT \ ??????????? const char *qt_plugin_query_metadata() \ ??????????? { return reinterpret_cast<const char *>(qt_pluginMetaData); } \ ??????????? Q_EXTERN_C Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance() \ ??????????? Q_PLUGIN_INSTANCE(PLUGINCLASS) 其中,Q_PLUGIN_INSTANCE,就是返回一个实例 #define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \ ??????? { \ ??????????? static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \ ??????????? if (!_instance) {??? \ ??????????????? QT_PLUGIN_RESOURCE_INIT \ ??????????????? _instance = new IMPLEMENTATION; \ ??????????? } \ ??????????? return _instance; \ ????? ??} Q_INTERFACES展开moc文件看到如下自动生成代码, ? 总结如下,
5.QT插件加载器QPluginLoader 首先,看看它的声明比较简单 ? 里面的instance返回对象实例指针,load()加载插件。上面声明中,有QJsonObject的定义来描述元数据,下面简单看一下元数据的描述格式Json 6. Json与插件元数据 Json是一种存储结构化数据的一种格式,概念中与xml类似,有6中基本数据类型: Bool, double, string, array, object与null. Json在插件中主要存储插件的元数据信息,在Qt中有一个专门的类QJsonObject对Json描述,与下表中其他配套的类一起来对Json管理。
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 23:50:47- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |