1.1 庫的概念 在我看來,庫是已經寫好的、成熟的、可復用的代碼。每個程式都需要依賴很多底層庫,不可能每個人的代碼從零開始編寫代碼,因此庫的存在具有非常重要的意義。 在我們的開發的應用中經常有一些公共代碼是需要反覆使用的,就把這些代碼編譯為庫文件。 庫可以簡單看成一組目標文件的集合,將這些目標文件經 ...
1.1 庫的概念
在我看來,庫是已經寫好的、成熟的、可復用的代碼。每個程式都需要依賴很多底層庫,不可能每個人的代碼從零開始編寫代碼,因此庫的存在具有非常重要的意義。
在我們的開發的應用中經常有一些公共代碼是需要反覆使用的,就把這些代碼編譯為庫文件。
庫可以簡單看成一組目標文件的集合,將這些目標文件經過壓縮打包之後形成的一個文件。像在Windows這樣的平臺上,最常用的c語言庫是由集成按開發環境所附帶的運行庫,這些庫一般由編譯廠商提供。
1.2 vs下靜態庫創建和使用
1.2.1 靜態庫的創建
1. 創建一個新項目,在已安裝的模板中選擇“常規”,在右邊的類型下選擇“空項目”,在名稱和解決方案名稱中輸入staticlib。點擊確定。 2.在解決方案資源管理器的頭文件中添加,mylib.h文件,在源文件添加mylib.c文件(即實現文件)。 3.在mylib.h文件中添加如下代碼:#ifndef TEST_H #define TEST_H int myadd(int a,int b); #endif |
#include"test.h" int myadd(int a, int b){ return a + b; } |
1.2.2 靜態庫的使用
方法一:配置項目屬性A、添加工程的頭文件目錄:工程---屬性---配置屬性---c/c++---常規---附加包含目錄:加上頭文件存放目錄。 B、添加文件引用的lib靜態庫路徑:工程---屬性---配置屬性---鏈接器---常規---附加庫目錄:加上lib文件存放目錄。 C 然後添加工程引用的lib文件名:工程---屬性---配置屬性---鏈接器---輸入---附加依賴項:加上lib文件名。 |
#pragma comment(lib,"./mylib.lib") |
就像你添加.h和.cpp文件一樣,把lib文件添加到工程文件列表中去. 切換到"解決方案視圖",--->選中要添加lib的工程-->點擊右鍵-->"添加"-->"現有項"-->選擇lib文件-->確定. |
1.2.3 靜態庫優缺點
n 靜態庫對函數庫的鏈接是放在編譯時期完成的,靜態庫在程式的鏈接階段被覆制到了程式中,和程式運行的時候沒有關係; n 程式在運行時與函數庫再無瓜葛,移植方便。 n 浪費空間和資源,所有相關的目標文件與牽涉到的函數庫被鏈接合成一個可執行文件。 |
1.3 vs下動態庫創建和使用
要解決空間浪費和更新困難這兩個問題,最簡單的辦法就是把程式的模塊相互分割開來,形成獨立的文件,而不是將他們靜態的鏈接在一起。簡單地講,就是不對哪些組成程式的目標程式進行鏈接,等程式運行的時候才進行鏈接。也就是說,把整個鏈接過程推遲到了運行時再進行,這就是動態鏈接的基本思想。1.3.1 動態庫的創建
1. 創建一個新項目,在已安裝的模板中選擇“常規”,在右邊的類型下選擇“空項目”,在名稱和解決方案名稱中輸入mydll。點擊確定。 2.在解決方案資源管理器的頭文件中添加,mydll.h文件,在源文件添加mydll.c文件(即實現文件)。 3.在test.h文件中添加如下代碼:#ifndef TEST_H #define TEST_H __declspec(dllexport) int myminus(int a, int b); #endif |
#include"test.h" __declspec(dllexport) int myminus(int a, int b){ return a - b; } |
疑問一:__declspec(dllexport)是什麼意思? 動態鏈接庫中定義有兩種函數:導出函數(export function)和內部函數(internal function)。 導出函數可以被其它模塊調用,內部函數在定義它們的DLL程式內部使用。 疑問二:動態庫的lib文件和靜態庫的lib文件的區別? 在使用動態庫的時候,往往提供兩個文件:一個引入庫(.lib)文件(也稱“導入庫文件”)和一個DLL(.dll)文件。雖然引入庫的尾碼名也是“lib”,但是,動態庫的引入庫文件和靜態庫文件有著本質的區別,對一個DLL文件來說,其引入庫文件(.lib)包含該DLL導出的函數和變數的符號名,而.dll文件包含該DLL實際的函數和數據。在使用動態庫的情況下,在編譯鏈接可執行文件時,只需要鏈接該DLL的引入庫文件,該DLL中的函數代碼和數據並不複製到可執行文件,直到可執行程式運行時,才去載入所需的DLL,將該DLL映射到進程的地址空間中,然後訪問DLL中導出的函數。 |
1.3.2 動態庫的使用
方法一:隱式調用創建主程式TestDll,將mydll.h、mydll.dll和mydll.lib複製到源代碼目錄下。 (P.S:頭文件Func.h並不是必需的,只是C++中使用外部函數時,需要先進行聲明) 在程式中指定鏈接引用鏈接庫 : #pragma comment(lib,"./mydll.lib") |
HANDLE hDll; //聲明一個dll實例文件句柄 hDll = LoadLibrary("mydll.dll"); //導入動態鏈接庫 MYFUNC minus_test; //創建函數指針 //獲取導入函數的函數指針 minus_test = (MYFUNC)GetProcAddress(hDll, "myminus"); |