看網上的好多關於QT調用Dll的方法,大部分都是調用函數的,並無調用C++類成員的狀況,即便是有,好比說:html
我就是按照這上面的教程一步步作的,惋惜了都沒成功~~~這裏面都有一個最重要的步驟沒有說清楚(可能怪我笨~~),路徑問題!!!ios
因此這裏自我作一下總結:app
建立時選擇C++ Library就能夠了,而後選擇Shared Library(共享庫),其餘默認OK。模塊化
建立好後文件以下(我這裏工程名爲:dll)函數
其中dll.pro代碼爲:post
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代碼爲:url
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代碼爲:spa
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代碼爲:.net
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)