C 靜態鏈結庫和動態鏈結庫

2021-07-05 20:50:47 字數 3556 閱讀 4771

專案、屬性、c/c++、附加包含目錄:填寫附加標頭檔案所在目錄 分號間隔多項

專案、屬性、鏈結器、常規、附加庫目錄:填寫附加依賴庫所在目錄 分號間隔多項

專案、屬性、鏈結器、輸入、附加依賴項:填寫附加依賴庫的名字.lib 空格或分號間隔多項

2)dynamic link library 的縮寫形式,dll是乙個包含可由多個程式同時使用的**和資料的庫,dll不是可執行檔案。動態鏈結提供了一種方法,使程序可以呼叫不屬於其可執行**的函式。函式的可執行**位於乙個 dll 中,該 dll 包含乙個或多個已被編譯、鏈結並與使用它們的程序分開儲存的函式。dll 還有助於共享資料和資源。多個應用程式可同時訪問記憶體中單個dll 副本的內容。dll 是乙個包含可由多個程式同時使用的**和資料的庫。

dll舉例

activex 控制項(.ocx) 檔案: 示例是日曆控制項,它使您可以從日曆中選擇日期。 ·

控制面板(.cpl) 檔案 :cpl 檔案的乙個示例是位於控制面板中的項。每個項都是乙個專用 dll。

·                     裝置驅動(.drv) 檔案

程式設計使用;

使用dll需注意三個檔案:

(1).h標頭檔案,包含dll中說明輸出的類或符號原型或資料結構的.h檔案。應用程式呼叫dll時,需要將該檔案包含入應用程式的原始檔中。

(2).lib檔案,是dll在編譯、鏈結成功之後生成的檔案,作用是當其他應用程式呼叫dll時,需要將該檔案引入應用程式,否則產生錯誤。如果不想用lib檔案或者沒有lib檔案,可以用win32 api函式loadlibrary、getprocaddress裝載。

(3).dll檔案,真正的可執行檔案,開發成功後的應用程式在發布時,只需要有.exe檔案和.dll檔案,並不需要.lib檔案和.h標頭檔案。

二,初步認識

共有兩種庫:

一種是lib包含了函式所在的dll檔案和檔案中函式位置的資訊(入口),**由執行時載入在程序空間中的dll提供,稱為動態鏈結庫dynamic link library。

一種是lib包含函式**本身,在編譯時直接將**加入程式當中,稱為靜態鏈結庫static link library。

共有兩種鏈結方式:

動態鏈結使用動態鏈結庫,允許可執行模組(.dll檔案或.exe檔案)僅包含在執行時定位dll函式的可執行**所需的資訊。

靜態鏈結使用靜態鏈結庫,鏈結器從靜態鏈結庫lib獲取所有被引用函式,並將庫同**一起放到可執行檔案中。

三,關於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裝載。

使用lib的方法:

靜態lib中,乙個lib檔案實際上是任意個obj檔案的集合,obj檔案是cpp檔案編譯生成的。在編譯這種靜態庫工程時,根本不會遇到鏈結錯誤;即使有錯,也只會在使用這個lib的ext檔案或者dll工程裡暴露出來。

在vc中新建乙個static library型別的工程lib,加入test.cpp檔案和test.h檔案(標頭檔案內包括函式宣告),然後編譯,就生成了lib.lib檔案。

別的工程要使用這個lib有兩種方式:

(1)在project->link->object/library module中加入lib.lib檔案(先查詢工程目錄,再查詢系統lib目錄);或者在源**中加入指令#pragma comment(lib, 「lib.lib」)。

(2)將lib.lib拷入工程所在目錄,或者執行檔案生成的目錄,或者系統lib目錄中。

(3)加入相應的標頭檔案test.h。

使用dll的方法:

使用動態鏈結中的lib,不是obj檔案的集合,即裡面不會有實際的實現,它只是提供動態鏈結到dll所需要的資訊,這種lib可以在編譯乙個dll工程時由編譯器生成。

建立dll工程的方法(略)。

(1)隱式鏈結

第一種方法是:通過project->link->object/library module中加入.lib檔案(或者在源**中加入指令#pragma comment(lib, 「lib.lib」)),並將.dll檔案置入工程所在目錄,然後新增對應的.h標頭檔案。

[html] 

#include "stdafx.h" 

#include "dllsample.h" 

#pragma comment(lib, "dllsample.lib") //你也可以在專案屬性中設定庫的鏈結 

int main() 

(2)顯式鏈結

需要函式指標和win32 api函式loadlibrary、getprocaddress裝載,使用這種載入方法,不需要.lib檔案和.h標頭檔案,只需要.dll檔案即可(將.dll檔案置入工程目錄中)。

[html] 

#include

#include //使用函式和某些特殊變數 

typedef void (*dllfunc)(int); 

int main() 

dllfunc = (dllfunc)getprocaddress(hinstlibrary, "testdll"); 

if (dllfunc == null) 

dllfunc(123); 

std::cin.get(); 

freelibrary(hinstlibrary); 

return(1); 

} loadlibrary函式利用乙個名稱作為引數,獲得dll的例項(hinstance型別是例項的控制代碼),通常呼叫該函式後需要檢視一下函式返回是否成功,如果不成功則返回null(控制代碼無效),此時呼叫函式freelibrary釋放dll獲得的記憶體。

getprocaddress函式利用dll的控制代碼和函式的名稱作為引數,返回相應的函式指標,同時必須使用強轉;判斷函式指標是否為null,如果是則呼叫函式freelibrary釋放dll獲得的記憶體。此後,可以使用函式指標來呼叫實際的函式。

最後要記得使用freelibrary函式釋放記憶體。

注意:應用程式如何找到dll檔案?

使用loadlibrary顯式鏈結,那麼在函式的引數中可以指定dll檔案的完整路徑;如果不指定路徑,或者進行隱式鏈結,windows將遵循下面的搜尋順序來定位dll:

(1)包含exe檔案的目錄

(2)工程目錄

(3)windows系統目錄

(4)windows目錄

(5)列在path環境變數中的一系列目錄

靜態鏈結庫和動態鏈結庫

其實再vc中,我們所用得所有api函式都封裝再下列三個dll檔案中 kernel32.dll 用於管理記憶體,程序和執行緒得各個函式 user32.dll 用於執行使用者介面任務,如視窗的建立和訊息的傳遞的各個函式 gdi32.dll 用於顯示文字和畫圖的各個函式 動態鏈結庫 我們再使用動態庫的時候...

靜態鏈結庫和動態鏈結庫

靜態鏈結庫 win32 static library 呼叫libtest.lib 動態dll win32 dynamic link library 跟librest的生成是一樣的 動態呼叫 成的.lib 和.dll 檔案拷入dllcall 工程所在的路徑,dllcall 執行下列 dll 中匯出函式...

靜態鏈結庫和動態鏈結庫

以前的時候寫過這方面的部落格,當時寫的時候都覺得已經懂了。今天閒著沒事幹,和咚哥他們去大華校招筆試遇到了這個問題。我突然間發現sdk沒寫三個月,把dll都忘記了。回來看了下,複習下。以前寫過程式的裝載和鏈結的部落格,那是os上面比較理論的。實際用函式庫的時候主要分為,靜態庫和動態庫,這裡就簡簡單單地...