什么是插件
重载了虚函数的dll,一个动态库
一.开发流程
1.定义接口集(必须全是纯虚函数)
2.用宏Q_DECLARE_INTERFACE()
将该接口告诉Qt元对象系统
Q_DECLARE_INTERFACE(NicIfAlgorithmLib, "NicIfAlgorithmLib") //第一个参数为接口类名 第二个参数为标识符
3.声明插件类,插件类继承Qobject和插件实现的接口
4.用宏Q_INTERFACES()
将插件接口告诉Qt元对象系统(在头文件中)。
Q_INTERFACES(NicIfAlgorithmLib) //接口类名
5.用宏Q_EXPORT_PLUGIN2()
导出插件类。
Q_EXPORT_PLUGIN2(nic.safeware.algorithmlib, NicAlgorithmLibCore) //导出Qt插件,第一参数为插件的IID,第二个参数为实现接口的类 自己没用这个
//换成其他的
Q_PLUGIN_METADATA()//让moc生成导出函数qt_plugin_instance(),供QPluginLoader()调用
6.用适当的.pro文件构建插件。
//.pro加上代码
// TEMPLATE = lib 生成插件
// TEMPLATE = app 生成应用程序
TEMPLATE = lib
CONFIG += plugin
plugins.pro文件
QT += core gui
CONFIG(debug, debug|release){
APP_DIR = $$PWD/../bin/debug/Demo
BIN_DIR = $$APP_DIR/bin
}else{
APP_DIR = $$PWD/../bin/release/Demo
BIN_DIR = $$APP_DIR/bin
}
DESTDIR = $$BIN_DIR #dll生成目录
TARGET = plugins
TEMPLATE = lib #生成库文件
HEADERS += \
plugins.h \
pluginsinractive.h
SOURCES += \
pluginsinractive.cpp
plugins.h 文件 声明接口函数
#ifndef PLUGINS_H
#define PLUGINS_H
#include <QtPlugin>
#include <QObject>
class plugins
{
public:
virtual ~plugins()
{
}
virtual int addNumber(int a,int b) = 0;
};
Q_DECLARE_INTERFACE(plugins,"plugins"); //①将该接口告诉宏对象
#endif // PLUGINS_H
pluginsintractive.h 实现接口函数头文件
#ifndef PLUGINSINTRACTIVE_H
#define PLUGINSINTRACTIVE_H
#include "plugins.h"
#include <QObject>
class pluginsIntractive : public QObject,public plugins
{
Q_OBJECT
Q_INTERFACES(plugins) //② 将接口告诉宏对象
Q_PLUGIN_METADATA(IID "plugins")//③ 让moc生成导出函数qt_plugin_instance(),供QPluginLoader()调用
public:
pluginsIntractive();
~pluginsIntractive();
int addNumber(int a, int b) Q_DECL_OVERRIDE;
};
#endif // PLUGINSINTRACTIVE_H
二.调用流程
- 包含接口头文件(只有纯虚函数的类)。
- 应用程序中用
QPluginLoader
来加载插件。 - 用宏
qobject_cast()
来判断一个插件是否实现了接口。
plugindemo.cpp
pluginDemo::pluginDemo(QWidget *parent)
: QMainWindow(parent)
{
QObject *obj = NULL;
QString serialPortPluginPath("./plugins.dll"); //插件dll的路径
QPluginLoader pluginLoader(serialPortPluginPath);//①加载插件
obj = pluginLoader.instance();
if(obj != NULL)
{
m_pInterface = qobject_cast<plugins*>(obj);
if(m_pInterface)//②判断是否实现插件
{
qDebug() << serialPortPluginPath<<"is loaded....";
int num = m_pInterface->addNumber(1,2);//③调用插件接口函数
qDebug() << "num: " << num;
}
}
else
{
qDebug()<<serialPortPluginPath<<"is loaded failed: "<<pluginLoader.errorString();
}
}