Qt-动态库的显示调用

调用方法

使用QLibrary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <QLibrary>
void LoadLibrary()
{
// 函数类型为void时
typedef void (*MyPrototype)(int, int);
// libPath为动态库路径
QLibrary lib("libPath");
// 函数名,C编译与C++编译的不同
MyPrototype func = lib.resolve("funcName");
if(func)
{
func(2,3);
}
}

注意事项

动态库路径

  • 当动态库和可执行文件目录或在系统目录时,只需要名称;
  • 当不同时,需要绝对路径。

    函数符号

funcName为动态库编译后的函数名,在Windows上,函数需要在编译时显示使用__declspec(dllexport)

此外,QT官方文档说该符号必须从库中导出为C函数,实际测试(基于Windows平台)其实是可以为C++函数的,需要通过调用约定的命名或DLL导出查看工具,找到对应函数的符号,如下:

C调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// export.h
extern "C" __declspec(dllexport) void MyFunction(int a, int b);
// export.cpp
extern "C" void MyFunction(int a, int b)
{
return a+b;
}
// import.cpp
void ImportMyFunction()
{
typedef void (*MyPrototype)(int, int);
QLibrary lib("export.dll");
MyPrototype func = lib.resolve("MyFunction");
if(func)
{
func(1,2);// 3
}
}

C++调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// export.h
__declspec(dllexport) void MyFunction(int a, int b);
// export.cpp
void MyFunction(int a, int b)
{
return a+b;
}
// import.cpp
void ImportMyFunction()
{
typedef void (*MyPrototype)(int, int);
QLibrary lib("export.dll");
MyPrototype func = lib.resolve("?MyFunction@YAXHH@Z");
if(func)
{
func(1,2);// 3
}
}

根据C++-调用约定的中命名或者使用DLL导出工具找到对应函数的符号,依旧可以获取到目标函数。

且使用C++函数时,才能函数重载。