目錄
一般創(chuàng)建方法
導(dǎo)出普通函數(shù)的方法&調(diào)用方法
導(dǎo)出類及其成員函數(shù)的方法&調(diào)用方法
眾所周知,我們可以將C++項目中的類以及函數(shù)導(dǎo)出,形成 .dll 文件,以供其他程序使用,下面將說明Qt環(huán)境下的使用方法。
首先創(chuàng)建共享庫,步驟如下:
下一步會出現(xiàn)類對話框等等,不用管它,直接點擊創(chuàng)建即可,稍后再將類都刪了。
創(chuàng)建好以后你會發(fā)現(xiàn)有一個包含global的頭文件,這個文件中定義了__declspec(dllexport)、__declspec(dllimport)等,也可以刪掉(如果要按照下面的方法的話,刪掉即可)。
接下來還有重要的一步,請在.pro文件中,加入
CONFIG += dll //即使你的代碼中寫成了 CONFIG += staticlib,也要改過來
接下來就開始我們具體的的創(chuàng)建方法吧!
按照導(dǎo)出dll的的操作劃分,有兩種模式:
導(dǎo)出普通方法(導(dǎo)出后可靜態(tài)調(diào)用,也可動態(tài)調(diào)用)
首先是頭文件內(nèi)容:
TESTDLLSHARED_EXPORT __declspec(dllexport) TESTDLLSHARED_EXPORT __declspec(dllimport)TESTDLLSHARED_EXPORT test2( test3( test4( a, b);
然后在對應(yīng)的cpp源文件中實現(xiàn)test1、test2、test3、test4這幾個方法(為了簡單,我只輸出了一句話):
<<<< test2(<<<< test3(<<<< test4( a,<<<<
接下來就可以創(chuàng)建了,創(chuàng)建成功后(創(chuàng)建失敗請仔細(xì)檢查,代碼已驗證過),你會在你的項目輸出目錄下找到一個和項目名稱一致的.dll文件。
OK!接下來我們來使用這個dll:
使用dll時有兩種調(diào)用方法,一種是靜態(tài)調(diào)用,一種是動態(tài)調(diào)用。
靜態(tài)調(diào)用
首先,創(chuàng)建一個常規(guī)的C++項目,將上面生成.dll復(fù)制到你的項目輸出目錄中(也就是和.exe文件在一起);
接下來,打開常規(guī)C++項目中的.pro文件,加入詳細(xì)的.dll文件地址,格式如下
LIBS += 項目輸出路徑\dll文件全稱
如我的就是
LIBS += D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.dll
D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release是我的項目輸出路徑,HpTickDll.dll是我的dll文件,使用時改動一下就好
接下來,將創(chuàng)建.dll文件時的頭文件復(fù)制到當(dāng)前項目路徑下,并添加到項目中,注意:如果你沒有按照我上面的#define條件定義方式,請重新寫__declspec(dllimport)。
接下來,在.cpp文件中包含該頭文件,就可以盡情地使用之前的函數(shù)了,如直接用test1()等等,就和平時編寫一樣的。
動態(tài)調(diào)用
?。。√貏e注意:我們在創(chuàng)建時沒有用到extern "C",也沒有用到.def 文件保持函數(shù)名不變(嘗試了很多次也不會用.def文件,會的歡迎留言),因此動態(tài)調(diào)用時函數(shù)名要改!因為編譯器已經(jīng)將函數(shù)名改了!
So,你一定會問我們怎么知道dll中的函數(shù)名變成啥了?不要著急,網(wǎng)上直接搜“.dll查看器”,遍地都是,下載下來后,選擇我們剛才的.dll文件就可以看了,下面是我們的這幾個函數(shù)test1、test2、test3、test4的新名稱(你的可能和我的不一樣哦):
請注意看紅色框中的部分(不要管其他的,我的文件里面還有其他東西),這就是四個函數(shù)在.dll文件中的名稱,我小小地猜測了一下,后面的v代表參數(shù)為void類型,i的個數(shù)代表int類型參數(shù)的個數(shù),前面的字母就不太清楚了(注意:參數(shù)個數(shù)并未正確列出,不過我們只需要正確的函數(shù)名,不影響)。
OK!這就好辦了!看步驟:
同樣是創(chuàng)建一個常規(guī)C++項目,不同的是.pro文件中不用加“LIBS += 項目輸出路徑\dll文件全稱”這句話了。
接下來在.cpp文件中寫主代碼(不用添加之前的頭文件):
#include <iostream><windows.h> typedef (CALLBACK * (CALLBACK *Fuci)( (CALLBACK *Fucii)(,=LoadLibrary(L Fucv t1=(Fucv)GetProcAddress(hdll,=(Fucv)GetProcAddress(hdll,=(Fuci)GetProcAddress(hdll,=(Fucii)GetProcAddress(hdll,,
以上就是普通函數(shù)創(chuàng)建.dll和使用.dll的方法,看起來動態(tài)調(diào)用是不是很麻煩?但它有許多優(yōu)點(請自查),而且據(jù)說這里的函數(shù)名可以利用.def文件實現(xiàn)不改變名稱,省去好多麻煩,但是我嘗試了各種方法,如在.pro中利用DEF_FILE添加.def文件還是不行55555,會的可以留言哦!
導(dǎo)出類及其成員函數(shù)(導(dǎo)出后可靜態(tài)調(diào)用。暫時不會動態(tài)調(diào)用,某些書上說類不支持動態(tài)調(diào)用,網(wǎng)上有說在類中寫一個方法返回類對象,但是個人認(rèn)為這種做法是不對的,因為此時肯定是用自己定義的函數(shù)指針去定義這個返回類對象方法,不可能成功【已驗證】,當(dāng)然或許還有更好的方法,有知道的歡迎交流哈)
對于類的話,創(chuàng)建時:在class的后面,類名的前面加上定義的__declspec(dllexport);使用時,換成__declspec(dllimport),也可以參照前面的#define條件定義法。舉例:
#define HPTICKDLLSHARED_EXPORT __declspec(dllexport)#ifdef HPTICKDLLSHARED_EXPORT#else#define HPTICKDLLSHARED_EXPORT __declspec(dllimport)#endifclass HPTICKDLLSHARED_EXPORT HpTickDll //我在這里定義了類HpTickDll{ public: int Start(); //注意成員函數(shù)之前不用加HPTICKDLLSHARED_EXPORT int GetTime();private: LARGE_INTEGER li; LONGLONG start, end, freq; int useTime; };
靜態(tài)調(diào)用的方法和普通函數(shù)一樣,直接可以使用類及其成員函數(shù)(別忘了添加頭文件),就不細(xì)說了。
『注:本文來自博客園“小溪的博客”,若非聲明均為原創(chuàng)內(nèi)容,請勿用于商業(yè)用途,轉(zhuǎn)載請注明出處http://www.cnblogs.com/xiaoxi666/』