Qt中純C++項目發布為dll的方法(超詳細步驟)

來源:互聯網
上載者:User

標籤:uil   完全   恢複   tar   實現   返回   cli   不同的   ogr   

目錄

  • 一般建立方法
  • 匯出普通函數的方法&調用方法
  • 匯出類及其成員函數的方法&調用方法

 

眾所周知,我們可以將C++項目中的類以及函數匯出,形成 .DLL 檔案,以供其他程式使用,下面將說明Qt環境下的使用方法。

首先建立共用庫,步驟如下:

下一步會出現類對話方塊等等,不用管它,直接點擊建立即可,稍後再將類都刪了。

建立好以後你會發現有一個包含global的標頭檔,這個檔案中定義了__declspec(dllexport)、__declspec(dllimport)等,也可以刪掉(如果要按照下面的方法的話,刪掉即可)。

接下來還有重要的一步,請在.pro檔案中,加入

CONFIG += dll  // 即使你的代碼中寫成了 CONFIG += staticlib,也要改過來

接下來就開始我們具體的的建立方法吧!

 

按照匯出dll的的操作劃分,有兩種模式:

  • 匯出普通方法(匯出後可靜態調用,也可動態調用)

首先是標頭檔內容:

 

標頭檔:在方法聲明時,前面加上__declspec(dllimport),也可用#define定義,看代碼://為了和將來用到的程式中公用一個標頭檔,建立dll時用到的是__declspec(dllexport),而使用dll時用到__declspec(dllimport),完全可以各自寫一下#define TESTDLLSHARED_EXPORT __declspec(dllexport)#ifdef TESTDLLSHARED_EXPORT#else#define TESTDLLSHARED_EXPORT __declspec(dllimport)#endif//下面我要定義4個普通函數:TESTDLLSHARED_EXPORT int test1();TESTDLLSHARED_EXPORT int test2(void);TESTDLLSHARED_EXPORT int test3(int a);TESTDLLSHARED_EXPORT int test4(int a,int b);

 然後在對應的cpp源檔案中實現test1、test2、test3、test4這幾個方法(為了簡單,我只輸出了一句話):

.cpp源檔案://記得加上上面的標頭檔//記得加上iostream標頭檔,不然cout不能用int test1(){    std::cout<<"test1"<<std::endl;}int test2(void){    std::cout<<"test2"<<std::endl;}int test3(int a){    std::cout<<"test3"<<std::endl;}int test4(int a,int b){    std::cout<<"test4"<<std::endl;}

接下來就可以建立了,建立成功後(建立失敗請仔細檢查,代碼已驗證過),你會在你的項目輸出目錄下找到一個和項目名稱一致的.dll檔案。

OK!接下來我們來使用這個dll:

使用dll時有兩種調用方法,一種是靜態調用,一種是動態調用。

  • 靜態調用

首先,建立一個常規的C++項目,將上面產生.dll複製到你的項目輸出目錄中(也就是和.exe檔案在一起);

接下來,開啟常規C++項目中的.pro檔案,加入詳細的.dll檔案地址,格式如下

 

LIBS += 項目輸出路徑\dll檔案全稱

如我的就是

LIBS += D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.dllD:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release是我的項目輸出路徑,HpTickDll.dll是我的dll檔案,使用時改動一下就好

接下來,將建立.dll檔案時的標頭檔複製到當前項目路徑下,並添加到項目中,注意:如果你沒有按照我上面的#define條件定義方式,請重新寫__declspec(dllimport)。

接下來,在.cpp檔案中包含該標頭檔,就可以盡情地使用之前的函數了,如直接用test1()等等,就和平時編寫一樣的。

  • 動態調用

!!!特別注意:我們在建立時沒有用到extern "C",也沒有用到.def 檔案保持函數名不變(嘗試了很多次也不會用.def檔案,會的歡迎留言),因此動態調用時函數名要改!因為編譯器已經將函數名改了!

So,你一定會問我們怎麼知道dll中的函數名變成啥了?不要著急,網上直接搜“.dll查看器”,遍地都是,下載下來後,選擇我們剛才的.dll檔案就可以看了,下面是我們的這幾個函數test1、test2、test3、test4的新名稱(你的可能和我的不一樣哦):

請注意看紅色框中的部分(不要管其他的,我的檔案裡面還有其他東西),這就是四個函數在.dll檔案中的名稱,我小小地猜測了一下,後面的v代表參數為void類型,i的個數代表int型別參數的個數,前面的字母就不太清楚了(注意:參數個數並未正確列出,不過我們只需要正確的函數名,不影響)。

OK!這就好辦了!看步驟:

同樣是建立一個常規C++項目,不同的是.pro檔案中不用加“LIBS += 項目輸出路徑\dll檔案全稱”這句話了。

接下來在.cpp檔案中寫主代碼(不用添加之前的標頭檔):

#include <iostream>#include <windows.h>int main(){    //首先定義函數指標,用來接收不同參數的函數    typedef int (CALLBACK *Fucv)();    typedef int (CALLBACK *Fuci)(int);    typedef int (CALLBACK *Fucii)(int,int);    //獲得.dll檔案的控制代碼,需要標頭檔windows.h的支援    HINSTANCE hdll=LoadLibrary(L"testDll.dll");     //L指寬字元串,若不寫L,則會出現錯誤,詳情請自查    //注意這裡要用.dll檔案中的函數名    Fucv t1=(Fucv)GetProcAddress(hdll,"_Z5test1v");    Fucv t2=(Fucv)GetProcAddress(hdll,"_Z5test2v");    Fuci t3=(Fuci)GetProcAddress(hdll,"_Z5test3i");    Fucii t4=(Fucii)GetProcAddress(hdll,"_Z5test4ii");    //現在的t1就執行的test1的功能,以此類推    t1();    t2();    t3(1);    t4(1,2);    FreeLibrary(hdll);    return 0;}

以上就是普通函數建立.dll和使用.dll的方法,看起來動態調用是不是很麻煩?但它有許多優點(請自查),而且據說這裡的函數名可以利用.def檔案實現不改變名稱,省去好多麻煩,但是我嘗試了各種方法,如在.pro中利用DEF_FILE添加.def檔案還是不行55555,會的可以留言哦!

  • 匯出類及其成員函數(匯出後可靜態調用。暫時不會動態調用,某些書上說類不支援動態調用,網上有說在類中寫一個方法返回類對象,但是個人認為這種做法是不對的,因為此時肯定是用自己定義的函數指標去定義這個返回類對象方法,不可能成功【已驗證】,當然或許還有更好的方法,有知道的歡迎交流哈)

對於類的話,建立時:在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();                       //注意成員函數之前不用加HPTICKDLLSHARED_EXPORT    int  GetTime();private:    LARGE_INTEGER li;    LONGLONG start, end, freq;    int useTime;};

靜態調用的方法和普通函數一樣,直接可以使用類及其成員函數(別忘了添加標頭檔),就不細說了。

---恢複內容結束---

目錄

  • 一般建立方法
  • 匯出普通函數的方法&調用方法
  • 匯出類及其成員函數的方法&調用方法

 

眾所周知,我們可以將C++項目中的類以及函數匯出,形成 .DLL 檔案,以供其他程式使用,下面將說明Qt環境下的使用方法。

首先建立共用庫,步驟如下:

下一步會出現類對話方塊等等,不用管它,直接點擊建立即可,稍後再將類都刪了。

建立好以後你會發現有一個包含global的標頭檔,這個檔案中定義了__declspec(dllexport)、__declspec(dllimport)等,也可以刪掉(如果要按照下面的方法的話,刪掉即可)。

接下來還有重要的一步,請在.pro檔案中,加入

CONFIG += dll  //即使你的代碼中寫成了 CONFIG += staticlib,也要改過來

接下來就開始我們具體的的建立方法吧!

 

按照匯出dll的的操作劃分,有兩種模式:

  • 匯出普通方法(匯出後可靜態調用,也可動態調用)

首先是標頭檔內容:

 

標頭檔:在方法聲明時,前面加上__declspec(dllimport),也可用#define定義,看代碼://為了和將來用到的程式中公用一個標頭檔,建立dll時用到的是__declspec(dllexport),而使用dll時用到__declspec(dllimport),完全可以各自寫一下#define TESTDLLSHARED_EXPORT __declspec(dllexport)#ifdef TESTDLLSHARED_EXPORT#else#define TESTDLLSHARED_EXPORT __declspec(dllimport)#endif//下面我要定義4個普通函數:TESTDLLSHARED_EXPORT int test1();TESTDLLSHARED_EXPORT int test2(void);TESTDLLSHARED_EXPORT int test3(int a);TESTDLLSHARED_EXPORT int test4(int a,int b);

 然後在對應的cpp源檔案中實現test1、test2、test3、test4這幾個方法(為了簡單,我只輸出了一句話):

.cpp源檔案://記得加上上面的標頭檔//記得加上iostream標頭檔,不然cout不能用int test1(){    std::cout<<"test1"<<std::endl;}int test2(void){    std::cout<<"test2"<<std::endl;}int test3(int a){    std::cout<<"test3"<<std::endl;}int test4(int a,int b){    std::cout<<"test4"<<std::endl;}

接下來就可以建立了,建立成功後(建立失敗請仔細檢查,代碼已驗證過),你會在你的項目輸出目錄下找到一個和項目名稱一致的.dll檔案。

OK!接下來我們來使用這個dll:

使用dll時有兩種調用方法,一種是靜態調用,一種是動態調用。

  • 靜態調用

首先,建立一個常規的C++項目,將上面產生.dll複製到你的項目輸出目錄中(也就是和.exe檔案在一起);

接下來,開啟常規C++項目中的.pro檔案,加入詳細的.dll檔案地址,格式如下

 

LIBS += 項目輸出路徑\dll檔案全稱

如我的就是

LIBS += D:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.dllD:\Desktop\Go\C++learnProgram\Qt\build-test_dll-Qt-Release\release是我的項目輸出路徑,HpTickDll.dll是我的dll檔案,使用時改動一下就好

接下來,將建立.dll檔案時的標頭檔複製到當前項目路徑下,並添加到項目中,注意:如果你沒有按照我上面的#define條件定義方式,請重新寫__declspec(dllimport)。

接下來,在.cpp檔案中包含該標頭檔,就可以盡情地使用之前的函數了,如直接用test1()等等,就和平時編寫一樣的。

  • 動態調用

!!!特別注意:我們在建立時沒有用到extern "C",也沒有用到.def 檔案保持函數名不變(嘗試了很多次也不會用.def檔案,會的歡迎留言),因此動態調用時函數名要改!因為編譯器已經將函數名改了!

So,你一定會問我們怎麼知道dll中的函數名變成啥了?不要著急,網上直接搜“.dll查看器”,遍地都是,下載下來後,選擇我們剛才的.dll檔案就可以看了,下面是我們的這幾個函數test1、test2、test3、test4的新名稱(你的可能和我的不一樣哦):

請注意看紅色框中的部分(不要管其他的,我的檔案裡面還有其他東西),這就是四個函數在.dll檔案中的名稱,我小小地猜測了一下,後面的v代表參數為void類型,i的個數代表int型別參數的個數,前面的字母就不太清楚了(注意:參數個數並未正確列出,不過我們只需要正確的函數名,不影響)。

OK!這就好辦了!看步驟:

同樣是建立一個常規C++項目,不同的是.pro檔案中不用加“LIBS += 項目輸出路徑\dll檔案全稱”這句話了。

接下來在.cpp檔案中寫主代碼(不用添加之前的標頭檔):

#include <iostream>#include <windows.h>int main(){    //首先定義函數指標,用來接收不同參數的函數    typedef int (CALLBACK *Fucv)();    typedef int (CALLBACK *Fuci)(int);    typedef int (CALLBACK *Fucii)(int,int);    //獲得.dll檔案的控制代碼,需要標頭檔windows.h的支援    HINSTANCE hdll=LoadLibrary(L"testDll.dll");     //L指寬字元串,若不寫L,則會出現錯誤,詳情請自查    //注意這裡要用.dll檔案中的函數名    Fucv t1=(Fucv)GetProcAddress(hdll,"_Z5test1v");    Fucv t2=(Fucv)GetProcAddress(hdll,"_Z5test2v");    Fuci t3=(Fuci)GetProcAddress(hdll,"_Z5test3i");    Fucii t4=(Fucii)GetProcAddress(hdll,"_Z5test4ii");    //現在的t1就執行的test1的功能,以此類推    t1();    t2();    t3(1);    t4(1,2);    FreeLibrary(hdll);    return 0;}

以上就是普通函數建立.dll和使用.dll的方法,看起來動態調用是不是很麻煩?但它有許多優點(請自查),而且據說這裡的函數名可以利用.def檔案實現不改變名稱,省去好多麻煩,但是我嘗試了各種方法,如在.pro中利用DEF_FILE添加.def檔案還是不行55555,會的可以留言哦!

  • 匯出類及其成員函數(匯出後可靜態調用。暫時不會動態調用,某些書上說類不支援動態調用,網上有說在類中寫一個方法返回類對象,但是個人認為這種做法是不對的,因為此時肯定是用自己定義的函數指標去定義這個返回類對象方法,不可能成功【已驗證】,當然或許還有更好的方法,有知道的歡迎交流哈)

對於類的話,建立時:在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();                       //注意成員函數之前不用加HPTICKDLLSHARED_EXPORT    int  GetTime();private:    LARGE_INTEGER li;    LONGLONG start, end, freq;    int useTime;};

靜態調用的方法和普通函數一樣,直接可以使用類及其成員函數(別忘了添加標頭檔),就不細說了。

Qt中純C++項目發布為dll的方法(超詳細步驟)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.