QT创建与调用Dll方法(包括类成员)--显式调用
看网上的好多关于QT调用Dll的方法,大部分都是调用函数的,并没有调用C++类成员的情况,即使是有,比如说:
Qt 一步一步实现dll调用(附源码)---(这一篇里没有调用类成员的)
Qt调用dll中的功能函数
我就是按照这上面的教程一步步做的,可惜了都没成功~~~这里面都有一个最重要的步骤没有说清楚(可能怪我笨~~),路径问题!!!
所以这里自我做一下总结:
创建时选择C++ Library就可以了,然后选择Shared Library(共享库),其他默认OK。
创建好后文件如下(我这里工程名为:dll)
其中dll.pro代码为:
1
2
3
4
5
6
7
8
9
10
11
12
|
TARGET = dll TEMPLATE = lib DEFINES += DLL_LIBRARY SOURCES += \ dll.cpp HEADERS +=\ dll_global.h \ dll.h unix { target.path = /usr/lib INSTALLS += target } |
dll_global.h代码为:
1
2
3
4
5
6
7
8
9
|
#ifndef DLL_GLOBAL_H #define DLL_GLOBAL_H #include <QtCore/qglobal.h> #if defined(DLL_LIBRARY) # define DLLSHARED_EXPORT Q_DECL_EXPORT #else # define DLLSHARED_EXPORT Q_DECL_IMPORT #endif #endif // DLL_GLOBAL_H |
dll.h代码为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#ifndef DLL_H #define DLL_H #include <string> #include "dll_global.h" using namespace std; class DLLSHARED_EXPORT Dll { public : Dll(); ~Dll(); void Print(); string GetStrAdd(string str1, string str2); }; extern "C" { DLLSHARED_EXPORT Dll* getDllObject(); //获取类Dll的对象 DLLSHARED_EXPORT void releseDllObject(Dll*); //获取类Dll的对象 DLLSHARED_EXPORT void helloWorld(); DLLSHARED_EXPORT int add( int a, int b); } #endif // DLL_H |
dll.cpp代码为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include "dll.h" #include <iostream> Dll::Dll() { std::cout<< "New Dll Object !" <<endl; } Dll::~Dll(){ std::cout<< "Dll Object Des~~" <<endl; } void Dll::Print () { std::cout<< "Dll::Print !" <<endl; } string Dll::GetStrAdd (string str1, string str2) { string s=str1+str2; std::cout<< "Dll::GetStrAdd->return->" <<s<<endl; return (s); } void helloWorld() { std::cout << "GlobalFun->hello,world!" <<endl; } int add( int a, int b) { std::cout<< "GlobalFun->add->return->" <<(a+b)<<endl; return a + b; } Dll* getDllObject() { return new Dll(); } void releseDllObject(Dll* dll){ delete dll; } |
运行后在生成目录里生成了dll.dll、libdll.a、dll.o三个文件(Windows下使用MinGW编译运行),如图:
其中,.dll是在Windows下使用的,.o是在Linux/Unix下使用的。新建一个调用项目”DllTest“:
将dll.h和dll_global.h两个文件放到代码目录中:
其中DllTest.pro代码如下:
1
2
3
4
5
6
|
greaterThan(QT_MAJOR_VERSION, 4 ): QT += widgets TARGET = DllTest TEMPLATE = app SOURCES += main.cpp LIBS +=dll.dll #很重要!路径设置问题,如果错了就没有如果了~~~ LIBS +=”D:/API/dll.dll" #~Right! |
如果路径中有空格存在,一定要把整个路径放到一对双引号里!
这里网友评论里提出了更为规范的写法,更规范的写法如下:(非常感谢博友:多多多多多!!!)
1
2
3
4
5
6
7
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = DllTest TEMPLATE = app SOURCES += main.cpp LIBS += -LD:/API -ldll #中间不能有空格 #当使用相对路径时(相对与下面要说的)可使用:
#LIBS += -L. -ldll
|
main.cpp代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
//#include <QtCore/QCoreApplication> #include <iostream> #include <QLibrary> #include "dll.h" //头文件还是需要加的,否则无法解析Dll类 typedef Dll* (*CreatDll)(); //定义函数指针,获取类Dll对象; typedef bool (*ReleseDll)(Dll*); typedef void (*fun)(); int main( ) { // QCoreApplication a(argc, argv); QLibrary mylib( "dll.dll" ); //声明所用到的dll文件 //判断是否正确加载 if (mylib.load()) { std::cout << "DLL loaded!" <<std::endl; CreatDll creatDll = (CreatDll)mylib.resolve( "getDllObject" ); ReleseDll decDll=(ReleseDll)mylib.resolve ( "releseDllObject" ); fun hello=(fun)mylib.resolve ( "helloWorld" ); if (hello)hello(); if (creatDll&&decDll) { Dll *testDll = creatDll(); testDll->GetStrAdd ( "abc" , "ABD" ); testDll->Print (); decDll(testDll); } } //加载失败 else std::cout << "DLL is not loaded!" <<std::endl; // return a.exec(); mylib.unload (); return 0; } //输出为: DLL loaded! GlobalFun->hello,world! New Dll Object ! Dll::GetStrAdd-> return ->abcABD Dll::Print ! Dll Object Des~~ |
这里将dll.dll文件放到调用项目的生成目录下(Debug上面一层)(这里对应上面的相对路径)即DllTest-Debug(我这里是这个名字,你那里可能不同)目录下:
编译,运行,OK!
这里要特别注意dll.dll的存放位置,还有要在.pro文件中增加一个 LIBS += dll.dll 用来指示路径,也可使用绝对路径如先将dll.dll放到D:/API/下,则应该设置为:LIBS += "D:/API/dll.dll"
如果想在资源管理器中直接双击exe文件打开,则dll.dll要放到和exe同目录下!
这个是显式调用的方法!
代码下载 http://download.csdn.net/detail/lomper/8183207
说明:下载的代码下载好后,要将LIBS += "D:/API/dll.dll" 更改成:LIBS += dll.dll 就可直接运行了。也可按规范写法:LIB += -LD:/API -ldll 或 LIBS+= -L. -ldll (注意这里的“ . ”而且中间-L和路径之间不能有空格)建议代码下载后更改成相对路径的方式(项目DllTest.pro)