使用qlibrary可以在程式執行時載入動態鏈結庫。乙個qlibrary的例項作用於乙個單一的共享庫上。qlibrary提供了一種平台無關的方式訪問庫中的函式。可以在構建qlibrary的例項時將要載入的庫檔案傳入,也可以在建立例項後使用setfilename()顯式的設定要載入的檔名。當載入庫檔案時,qlibrary會搜尋所有平台特定的庫位置,除非傳入的檔名具有絕對路徑。
如果傳入的檔名具有絕對路徑,那麼會首先嘗試載入該目錄。如果該檔案找不到,qlibrary會使用不同的平台特定的檔案字首或字尾再次嘗試,比如unix和mac平台的"lib"字首,unix平台的".so"字尾,mac平台的".dylib",windows平台的".dll"。如果檔名不是絕對路徑,qlibrary會修改搜尋順序,首先嘗試系統特定的字首和字尾,緊接著是指定的檔案路徑。
所以,基於qlibrary對庫檔案的搜尋機制,我們推薦在傳入庫檔案時只傳入該庫檔案的基名,不寫字首或字尾。這樣一來,同乙份**可以在不同的作業系統上工作,並且該機制會保證進行最小次數的搜尋。
該類中最重要的函式是load(),該函式動態的載入庫檔案,isloaded()可以用來檢查庫檔案是否成功載入,而resolve()函式則用來解析庫中的符號位址,主要是函式位址。並且,resolve()函式在庫檔案未被載入時會隱式的嘗試載入它。多個qlibrary例項可以可以訪問同乙個庫檔案。因為,庫檔案一旦被載入,就會駐留在記憶體中直到應用程式終止。當然,我們可以使用unload()函式來嘗試解除安裝乙個庫檔案,但是如果有其他的qlibrary例項正在引用同乙個庫檔案,unload()會呼叫失敗,並且該庫檔案會在所以例項都呼叫了unload()後才被解除安裝。
qlibrary庫的典型用法是去解析乙個庫中的匯出符號,並呼叫該符號表示的c函式。這被稱為「顯式鏈結」,而相對的「隱式鏈結」是在編譯過程的鏈結階段完成的。如下面的**顯示的那樣,改**先載入乙個庫,解析其中的"mysymbol"符號,並在成功的情況下,呼叫該函式。如果由於某種原因出錯了,例如庫檔案不存在或該符號未被定義,那麼相應的函式指標將被設為空,不會發生實際的呼叫:
qlibrary mylib("mylib");
typedef void (*myprototype)();
myprototype myfunction = (myprototype) mylib.resolve("mysymbol");
if (myfunction)
myfunction();
但該符號必須被匯出為c函式。也就是說,如果該庫是由c++編譯器編譯的,那麼該函式必須被包在extern "c"塊中。並且在windows平台上,還需要使用dllexport巨集來修飾該函式。
出於方便,該類還提供了乙個靜態的resolve()函式,我們可以使用該函式來解析並呼叫乙個庫中的方法,而不需要先載入該庫。如下**所示:
typedef void (*myprototype)();
myprototype myfunction =
(myprototype) qlibrary::resolve("mylib", "mysymbol");
if (myfunction)
myfunction();
其實,除了靜態的resolve()函式,該類還提供了乙個靜態的islibrary()函式,該函式可以根據特定平台來判斷乙個檔案是否是可被載入的庫。其所使用的規則如下:
平台有效字尾
windows
.dll,.dll
unix/linux
.soaix
.ahp-ux
.sl,.so(hp-uxi)
os x and ios
.dylib,.bundle,.so
下面,我們通過乙個例項來簡單使用一下該類。
我們先使用qtcreator來寫乙個dll工程,工程名為add,在該dll中提供乙個函式,完成兩個數字的加法。**如下:
在add.h中宣告函式,如下:
#ifndef add_h
#define add_h
#include "add_global.h"
extern "c" addshared_export int myadd(int a, int b);
#endif // add_h
在add.cpp中實現該函式,如下:
#include "add.h"
int myadd(int a, int b)
編譯,生成dll即可。
我們接下來在建乙個qt控制台測試工程testadd。**如下:
#include
#include
#include
intmain(int
argc,
char
*argv)
typedefint(*myadd)(int,int);
myaddmyadd=(myadd)lib.resolve("myadd");
if(myadd)
else
returna.exec();
}將上面生成的add.dll檔案拷貝到該測試工程的編譯目錄下即可。執行結果如下:
使用QLibrary載入動態庫
使用qlibrary可以在程式執行時載入動態鏈結庫。乙個qlibrary的例項作用於乙個單一的共享庫上。qlibrary提供了一種平台無關的方式訪問庫中的函式。可以在構建qlibrary的例項時將要載入的庫檔案傳入,也可以在建立例項後使用setfilename 顯式的設定要載入的檔名。當載入庫檔案時...
QT 使用QLibrary載入動態庫
原文 1 win下動態庫呼叫有關的函式包括 1 loadlibrary,裝載動態庫。2 getprocaddress,獲取要引入的函式,將符號名或標識號轉換為dll內部位址。3 freelibrary,釋放動態鏈結庫。2 unix上與動態庫呼叫有關的函式包括 1 開啟動態鏈結庫 dlopen,函式原...
QLibrary 動態載入dll
qt下qlibrary動態載入dll是本文要介紹的內容,先來配置環境,測試平台 windows xp sp3 qt 4.5 compaq visual fortran version 6.6。下了個qt creator功能挺強大的,測試一下qlibrary動態載入vs下編譯的fortran寫的dll...