插件和dll区别:
插件
插件主要面向接口编程,无需访问.lib文件,热插拔、利于团队开发。即使在程序运行时.dll不存在,也可以正常启动,只是相应插件功能无法正常使用而已;
调用插件中的方法只要dll即可,不需要头文件和lib文件(可以把头文件放进来,不然不知道具体接口)
动态库
动态库需要访问.lib文件,而且在程序运行时必须保证.lib存在,否则无法正常启动;
QPluginLoader::load()方法返回false的一些解决办法:
(1)在环境变量加QT_DEBUG_PLUGINS = 1, 可以查看一些打印信息
(2)接口实现类没有Q_OBJECT
(3)进行了Q_PLUGIN_METADATA的声明,但是json文件格式错误
(4)出现PluginLoader returns a QObject instance, but qobject_cast returns null (0x0)此问题
原因1: 接口文件不统一 Q_DECLARE_INTERFACE的id不一样
(5)pluginLoader.errorString()查看错误信息
(6)该项目下依赖的外部库dll在编译的时候没有放到debug目录下
插件一些注意事项:
(1)关闭程序时插件是否自动析构插件内的所有对象取决于
//QPluginLoader 加载插件名(直接声明对象在关闭程序时自动析构所有插件,如果声明对象指针则需要手动析构所有插件) QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName));
插件创建流程:
(1)写一个抽象类,把用到的插件方法抽象成纯虚函数,抽象类要加上虚析构。
(2)抽象类中需要声明一个插件的唯一标识,例如:
#define AbstractInterface_iid “log plugin”
(3)声明接口,Q_DECLARE_INTERFACE 宏告诉Qt 这个纯虚类是一个插件接口类,例如:
Q_DECLARE_INTERFACE(LogPlugin, AbstractInterface_iid)
(4)插件实现类需要继承QObject和抽象类,宏Q_INTERFACES(LogPlugin)把插件注册到QT元对象系统中,宏Q_PLUGIN_METADATA导出插件和包含插件的json信息
插件中信号槽的使用:
插件是一个接口类,里面都是纯虚函数,正常不用继承QObject,也不用加Q_OBJECT
声明一个信号:(接口类中把信号声明为纯虚函数,不用加signals:),槽函数同理
实现类中要加上signals:并重写updateTabWidgetPage,这里是信号所以没有具体实现,然后直接在实现类中发信号即可,槽函数同理,但槽函数有具体实现。
信号槽连接需要把插件类转为QObject*