1. 程式人生 > 實用技巧 >Qt新增連結庫總結

Qt新增連結庫總結

Qt新增連結庫總結

一 前言:
在Qt工程開發過程中,經常會碰到整合第三方庫的情況,不論是靜態庫還是動態庫。由於Qt本身不完善等特性,整合過程中經常會出現各種各樣的問題。針對遇到過的問題記錄如下備忘,同時也希望能為更多開發者朋友提供前車之鑑。
二 基礎知識簡介:
2.1關於lib和dll的區別如下:
  (1)lib是編譯時用到的,dll是執行時用到的。如果要完成原始碼的編譯,只需要 lib;如果要使動態連結的程式執行起來,只需要dll。
  (2)如果有dll檔案,那麼lib一般是一些索引資訊,記錄了dll中函式的入口和位 置,dll中是函式的具體內容;如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。使用靜態編譯的lib檔案,在執行程式時 不需要再掛動態庫,缺點是導致應用程式比較大,而且失去了動態庫的靈活性,釋出新版本時要釋出新的應用程式才行。

  (3)動態連結的情況下,有兩個 檔案:一個是LIB檔案,一個是DLL檔案。LIB包含被DLL匯出的函式名稱和位置,DLL包含實際的函式和資料,應用程式使用LIB檔案連結到DLL 檔案。在應用程式的可執行檔案中,存放的不是被呼叫的函式程式碼,而是DLL中相應函式程式碼的地址,從而節省了記憶體資源。DLL和LIB檔案必須隨應用程式 一起發行,否則應用程式會產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用WIN32 API函式LoadLibrary、GetProcAddress裝載。

三 載入方式:

3.1連結的兩種方式

轉:

顯示呼叫

(該方式只使適用只有dll檔案的例子,在此情況下,dll實現的函式名及引數應該是已知的)

Qt提供了一個 QLibrary 類供顯示呼叫。下面給出一個完整的例子:

#include
#include
#include
#include
#include “dll.h” //引入標頭檔案
typedef int (*Fun)(int,int); //定義函式指標,以備呼叫
int main(int argc,char **argv)
{
QApplication app(argc,argv);
QLibrary mylib(“myDLL.dll”); //宣告所用到的dll檔案
int result;
if (mylib.load()) //判斷是否正確載入
{ QMessageBox::information(NULL,“OK”,“DLL load is OK!”); Fun open=(Fun)mylib.resolve(“add”); //援引 add() 函式 if (open) //是否成功連線上 add() 函式 { QMessageBox::information(NULL,“OK”,“Link to Function is OK!”); result=open(5,6); //這裡函式指標呼叫dll中的 add() 函式 qDebug()<<result; } else QMessageBox::information(NULL,“NO”,“Linke to Function is not OK!!!”); } else QMessageBox::information(NULL,“NO”,“DLL is not loaded!”); return 0; //載入失敗則退出

myDLL.dll為自定義的dll檔案,將其複製到程式的輸出目錄下就可以呼叫。顯然,顯示呼叫程式碼書寫量巨大,實在不方便。
隱式呼叫
這個時候我們需要三個檔案,標頭檔案(.h)、匯入庫檔案(.lib)、動態連結庫(.dll),具體步驟如下:
1、首先我們把 .h 與 .lib/.a 檔案複製到程式當前目錄下,然後再把dll檔案複製到程式的輸出目錄,
2、下面我們在pro檔案中,新增 .lib 檔案的位置: LIBS+= -L D:/hitempt/api/ -l myDLL
-L 引數指定 .lib/.a 檔案的位置
-l 引數指定匯入庫檔名(不要加副檔名)
另外,匯入庫檔案的路徑中,反斜槓用的是向右傾斜的
3、在程式中include標頭檔案(我試驗用的dll是用C寫的,因此要用 extern “C” { #include “dll.h” } )

下面是隱式呼叫的例項程式碼:

#include
#include
extern “C” //由於是C版的dll檔案,在C++中引入其標頭檔案要加extern “C” {},注意
{
#include “dll.h”
}
int main(int argv ,char **argv)
{
QApplication app(argv,argv);
HelloWordl(); //呼叫Win32 API 彈出helloworld對話方塊
qDebug()<<add(5,6); // dll 中我自己寫的一個加法函式
return 0; //完成使命後,直接退出,不讓它進入事件迴圈
}

3.2lib地址在pro檔案中的寫法
網友提供了一下這種方法,其中相當有借鑑之處。但我用後發現卻編譯失敗(Qt5.6.1 Qt creator4.5.1),主要原因在與:lib檔案的地址必須使用相對地址,而不是絕對地址,將一下地址改為:
LIBS += -L…/與工程目錄同級的、放置lib的資料夾名/ -l後面緊跟lib檔名
就通過了。
在.pro檔案中,加上一句話,告訴工程,.lib在哪裡
LIBS += -LE:/project/QT/usbcan_info/ -lControlCAN
下面對這句話進行解析:
1)+=這個符號是連線在一起的,不要自做聰明,給分開了,寫成+ = ,這樣就是錯的!
2)+=的左右兩邊可以有空格,也可以沒有空格,隨意的
3)-L之後緊接著就跟著.lib檔案所在的目錄,比如,我的目錄是在E盤下的project目錄下的QT目錄下的usbcan_info下,注意,是緊跟著,不要分開,分開就錯啦!
4)-l後面跟著的是.lib的檔名,注意,比如你的.lib檔案時ControlCAN.lib,不要傻乎乎的寫成了-lControlCAN.lib,不要帶字尾,要寫成-lControlCAN,同樣,-l後面也沒有空格

3.3關於相對目錄的問題
在上一點中提到的相對目錄的表示,例如-L …/debug/ ,debug不是當前工程所處的資料夾下的debug檔案,而是和工程所在目錄同級的,因此一定要記清楚。