大多数人重视回报,少数人管理风险,极少数人会去理解时间的价值

QLibrary类,Qt提供的加载C/C++动态链接库的方法,主要接口如下:

一、导出函数示例

1
2
3
4
5
extern "C" void printString(const QString &);
void printString(const QString & string)
{
qDebug() << string << endl;
}

C++生成动态库DLL的同时生成Lib(保存导出符号),需要在工程中添加导出方法或导出类,修改上述接口如下:

1
extern "C" __declspec(dllexport) void printString(const QString &);

二、加载DLL示例

将上述工程生成的Lib和DLL文件复制到exe同级目录,加载代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/// \brief 加载DLL
/// \param libFile DLL文件路径
bool loadLibrary(const QString &libFile)
{
QLibrary library(libFile);
if (library.load())
{
typedef void(*PrintString)(const QString &);
PrintString function = (PrintString)library.resolve("printString");
if (function)
{
QString string = "qiangu";
PrintString(string);
}
library.unload();
return true;
}
else
{
// 加载失败
QString strLog = library.errorString();
return false;
}
}

上述示例如果DLL和exe在同级目录,运行无问题;如果DLL和不在同级目录,在QtCreator中可运行,在VS报错找不到print.dll,双击exe运行报错找不到print.dll(在VS中,设置属性-调试-环境,设置DLL路径可解决问题,但是双击运行还是会报错找不到DLL–类似解决方案一,仅设置VS的环境变量),百度到的几种解决方案:

  1. 将DLL复制到C:/Windows/System32,或者将DLL目录加到系统环境变量;
  2. Windows延时加载;

三、延时加载

第一种方案可临时解决开发问题,实际程序打包到其它机器上运行不方便,需要做复制操作或设置系统环境变量,第二种方案如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#if WIN32
#include <Windows.h>
#endif

/// \brief 加载DLL
/// \details plugins目录与exe同级
bool loadLibrary()
{
QString strDllPath = QApplication::applicationDirPath() + "/plugins/print.dll";
#if WIN32
SetDllDirectoryA(QFileInfo(strDllPath).absoluteDir().path().toStdString().c_str());
return loadLibrary(strDllPath);
#endif
}

以上情况只针对Windows,Linux可以写脚本启动程序,在脚本中设置LD_LIBRARY_PATH路径,添加DLL路径即可。