使用QT5创建动态库以及如何在程序运行时加载动态库
本文介绍了如何使用QT5创建动态库,以及如何在程序运行时加载动态库。这种方式类似于Qt的应用程序插件机制,插件的方式可以直接获取动态库中类的实例,而此方式只能到函数级,从库中获取函数的地址并转换为对应的函数指针来执行。
下面以实例进行介绍:
创建动态库
- 新建库项目,pro文件如下:
QT += widgets
TEMPLATE = lib #输出为动态库
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
TARGET= mplugin
SOURCES += \
mplugin.cpp
HEADERS += \
mplugin.h
- 将cpp中需要导出的函数用extern “C”
#ifndef MPLUGIN_H
#define MPLUGIN_H
#include <QObject>
/* QT在windows下导出符号必须要用“__declspec(dllexport)”修饰,否则QLibrary会加载失败 */
#ifdef Q_OS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif
class Mplugin
{
public:
Mplugin();
void show(QString s);
};
#endif // MPLUGIN_H
#include "mplugin.h"
#include <QMessageBox>
#include <QWidget>
Mplugin::Mplugin()
{
}
//调用此函数显示一个消息框
void Mplugin::show(QString s)
{
QWidget w;
QMessageBox::warning(&w,"warning!",s);
}
extern "C" MY_EXPORT void myShow(QString s)
{
Mplugin plu;
plu.show(s);
}
使用动态库
新建另一项目,源码如下:
#include <QApplication>
#include <QLibrary>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
/* 加载库文件,可以使用绝对路径或相对路径,mplugind.dll为上面动态库项目编译产生的二进制库文件 */
QLibrary lib("D:/Documents/build-mmplugin-Desktop_x86_windows_msvc2019_pe_64bit-Debug/mplugin/debug/mplugind.dll");
typedef void (*FUN)(QString); //此格式同导出符号的格式
/* 解析动态库中的符号,如果不存在会返回NULL */
FUN fun = (FUN)lib.resolve("myShow");
if (fun) {
fun("test"); //运行到此处会显示消息框
}
return a.exec();
}
注意事项
- 编写为动态库的代码中,所有需要外部调用的函数必须为C函数,Cpp中需要使用extern "C"导出。
- windwos下导出的符号需要使用extern “C” __declspec(dllexport)**来修饰。可以在头文件中加入如下的代码段,然后在源代码文件中所有需要导出的CPP函数加上extern “C” MY_EXPORT即可实现不修改代码就可以在不同的系统下使用。
#ifdef Q_OS_WIN
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif