创建Qt5应用程序插件

前言

最近也没时间来写博客了 (⊙o⊙)…,于是现在赶紧抽空写一写~~这次讲的是在创建Qt插件,在Windows上为.dll动态库,Linux上为.so动态库

官网>> How to Create Qt Plugins

大概就是这么几步

Making an application extensible through plugins involves the following steps:

  • Define a set of interfaces (classes with only pure virtual functions) used to talk to the plugins.
  • Use the Q_DECLARE_INTERFACE() macro to tell Qt’s meta-object system about the interface.
  • Use QPluginLoader in the application to load the plugins.
  • Use qobject_cast() to test whether a plugin implements a given interface.

Writing a plugin involves these steps:

  • Declare a plugin class that inherits from QObject and from the interfaces that the plugin wants to provide.
  • Use the Q_INTERFACES() macro to tell Qt’s meta-object system about the interfaces.
  • Export the plugin using the Q_PLUGIN_METADATA() macro.
  • Build the plugin using a suitable .pro file.

**注意:**Q_EXPORT_PLUGIN,Q_EXPORT_PLUGIN2 宏在Qt5不能用了,用新的宏 Q_PLUGIN_METADATA

生成插件

创建一个应用程序插件,要先创建一个插件接口类(interface),它只能包含,再创建一个插件类,并继承自这个接口类。下面以一个简单的例子说明:)

(新建一个空的Qt项目)

mytestplugininterface.h 接口类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef MYTESTPLUGININTERFACE_H
#define MYTESTPLUGININTERFACE_H
#include<QString>
#include<QObject>
class MyTestPluginInterface
{
public:
virtual ~MyTestPluginInterface(){}
//纯虚函数
virtual void helloworld(QString string)=0;
};
//第二个参数指定 唯一IID标识符,其实就是个字符串
Q_DECLARE_INTERFACE(MyTestPluginInterface,"myplugin.example.my.com")
#endif // MYTESTPLUGININTERFACE_H

mytestplugin.h 插件类头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef MYTESTPLUGIN_H
#define MYTESTPLUGIN_H
#include"mytestplugininterface.h"
#include<QObject>
class MyTestPlugin:public QObject,MyTestPluginInterface
{
Q_OBJECT
//导出该插件
Q_PLUGIN_METADATA(IID "myplugin.example.my.com")
//将该接口注册到Qt的元对象系统
Q_INTERFACES(MyTestPluginInterface)
public:
MyTestPlugin();
void helloworld(QString string);
~MyTestPlugin(){}
};
#endif // MYTESTPLUGIN_H

mytestplugin.cpp 插件类cpp源文件

1
2
3
4
5
6
7
8
#include"mytestplugin.h"
#include<QtPlugin>
#include<QDebug>
MyTestPlugin::MyTestPlugin(){}
//重写该接口类的虚函数
void MyTestPlugin::helloworld(QString string){
qDebug()<<"Hello---> "<<string;
}

最后就是编辑.pro文件并构建该插件

1
2
3
4
5
6
7
8
9
TEMPLATE = lib
CONFIG += plugin
TARGET = mytestPlugin
DESTDIR = ../outputDir
HEADERS += \
mytestplugin.h \
mytestplugininterface.h
SOURCES += \
mytestplugin.cpp

CONFIG 表明要构建一个插件
TARGET 指定生成的.dll 或 .so 文件名
DESTDIR 指定生成的.dll 或 .so 文件所在的目录

最后还要把本地部署改为Release,然后在构建该项目即可生成指定的库文件,比如我的是 libmytestPlugin.so

测试插件

为了做一个简单的测试,我另外创建了一个项目,调用插件也很简单,这里给出核心代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//用QPluginLoader加载动态链接库,注意QLibrary类与QPluginLoader类的区别
#include<QPluginLoader>
#include"mytestplugininterface.h"
void Dialog::loadmyPlugin()
{
QPluginLoader *loader=new QPluginLoader(this);
//把插件文件和包含插件声明的文件放到项目下
loader->setFileName("libmytestPlugin.so");
//判断加载插件是否成功
if(!loader->load()){
qDebug()<<"Error:"<<loader->errorString();
return;
}
//遍历插件的元数据信息
foreach (QString key,loader->metaData().keys()) {
qDebug()<<key<<"\t"<<loader->metaData().value(key);
}
QObject*plugin= loader->instance();
//转换获取插件类对象
MyTestPluginInterface *mytestpliugin=qobject_cast<MyTestPluginInterface*>(plugin);
mytestpliugin->helloworld("Google...");
//卸载插件
loader->unload();
}

ok,到此基本上完成了一个简单的插件使用了 :)


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!