lib 和 dll 的区别、生成以及使用详解
【目錄】
lib dll介紹
生成動態(tài)庫
調(diào)用動態(tài)庫
生成靜態(tài)庫
調(diào)用靜態(tài)庫
?
首先介紹一下靜態(tài)庫(靜態(tài)鏈接庫)、動態(tài)庫(動態(tài)鏈接庫)的概念,首先兩者都是代碼共享的方式。
靜態(tài)庫:在鏈接步驟中,連接器將從庫文件取得所需的代碼,復(fù)制到生成的可執(zhí)行文件中,這種庫稱為靜態(tài)庫,其特點是可執(zhí)行文件中包含了庫代碼的一份完整拷貝;缺點就是被多次使用就會有多份冗余拷貝。即靜態(tài)庫中的指令都全部被直接包含在最終生成的 EXE 文件中了。在vs中新建生成靜態(tài)庫的工程,編譯生成成功后,只產(chǎn)生一個.lib文件
動態(tài)庫:動態(tài)鏈接庫是一個包含可由多個程序同時使用的代碼和數(shù)據(jù)的庫,DLL不是可執(zhí)行文件。動態(tài)鏈接提供了一種方法,使進(jìn)程可以調(diào)用不屬于其可執(zhí)行代碼的函數(shù)。函數(shù)的可執(zhí)行代碼位于一個 DLL 中,該 DLL 包含一個或多個已被編譯、鏈接并與使用它們的進(jìn)程分開存儲的函數(shù)。在vs中新建生成動態(tài)庫的工程,編譯成功后,產(chǎn)生一個.lib文件和一個.dll文件
那么上述靜態(tài)庫和動態(tài)庫中的lib有什么區(qū)別呢?
靜態(tài)庫中的lib:該LIB包含函數(shù)代碼本身(即包括函數(shù)的索引,也包括實現(xiàn)),在編譯時直接將代碼加入程序當(dāng)中
動態(tài)庫中的lib:該LIB包含了函數(shù)所在的DLL文件和文件中函數(shù)位置的信息(索引),函數(shù)實現(xiàn)代碼由運行時加載在進(jìn)程空間中的DLL提供
總之,lib是編譯時用到的,dll是運行時用到的。如果要完成源代碼的編譯,只需要lib;如果要使動態(tài)鏈接的程序運行起來,只需要dll。
以下例子均在vs2010上測試
生成和使用動態(tài)庫
生成動態(tài)庫
?新建項目--win32項目--填寫項目名--確定--下一步--應(yīng)用程序類型:選擇dll--附加選項:選擇導(dǎo)出符號--完成
可以看到生成了一個dllmain.cpp 文件,這是dll應(yīng)用程序的入口,注意它和普通工程的入口main函數(shù)不同,這個文件我們不需要修改。
?在這個動態(tài)庫中我們舉例導(dǎo)出一個變量,一個類,一個函數(shù),頭文件dll.h如下:
1 //新建生成dll的工程時,vs默認(rèn)定義了宏DLL_EXPORT,因此,DLL_API 是 __declspec(dllexport),用來導(dǎo)出 2 //當(dāng)我們在靜態(tài)調(diào)用dll時,我們包含該頭文件,由于沒有定義DLL_EXPORT,所以DLL_API是 3 //__declspec(dllimport),用來導(dǎo)入 4 #ifdef DLL_EXPORTS 5 #define DLL_API __declspec(dllexport) 6 #else 7 #define DLL_API __declspec(dllimport) 8 #endif 9 10 // 導(dǎo)出類 11 class DLL_API Cdll { 12 public: 13 Cdll(void); 14 // TODO: 在此添加您的方法。 15 }; 16 17 //導(dǎo)出變量,變量在.cpp文件中定義 18 extern DLL_API int ndll; 19 20 //導(dǎo)出函數(shù),加extern "C",是為了保證編譯時生成的函數(shù)名不變,這樣動態(tài)調(diào)用dll時才能 21 //正確獲取函數(shù)的地址 22 extern "C" DLL_API int fndll(void);dll.cpp 文件如下:
1 #include "dll.h" 2 3 4 // 這是導(dǎo)出變量的一個示例 5 DLL_API int ndll=6; 6 7 // 這是導(dǎo)出函數(shù)的一個示例。 8 DLL_API int fndll(void) 9 { 10 return 42; 11 } 12 13 // 這是已導(dǎo)出類的構(gòu)造函數(shù)。 14 // 有關(guān)類定義的信息,請參閱 dll.h 15 Cdll::Cdll() 16 { 17 return; 18 }調(diào)用動態(tài)庫
有兩種方法調(diào)用動態(tài)庫,一種隱式鏈接,一種顯示鏈接。
調(diào)用動態(tài)庫:隱式鏈接
隱式鏈接 需要.h文件,dll文件,lib文件
(1)將dll放到工程的工作目錄
(2)設(shè)置項目屬性--vc++目錄--庫目錄為lib所在的路徑
(3)將lib添加到項目屬性--鏈接器--輸入--附加依賴項(或者直接在源代碼中加入#pragma comment(lib, “**.lib”))
(4)在源文件中添加.h頭文件
然后就像平常一樣調(diào)用普通函數(shù)、類、變量
調(diào)用動態(tài)庫:顯示鏈接
顯示鏈接 只需要.dll文件,但是這種調(diào)用方式不能調(diào)用dll中的變量或者類(其實可以調(diào)用類,但是相當(dāng)麻煩,有興趣者可參考http://blog.csdn.net/jdcb2001/article/details/1394883)
顯示調(diào)用主要使用WIN32 API函數(shù)LoadLibrary、GetProcAddress,舉例如下:
1 typedef int (*dllfun)(void);//定義指向dll中函數(shù)的函數(shù)指針 2 HINSTANCE hlib = LoadLibrary(".\\dll.dll"); 3 if(!hlib) 4 { 5 std::cout<<"load dll error\n"; 6 return -1; 7 } 8 dllfun fun = (dllfun)GetProcAddress(hlib,"fndll"); 9 if(!fun) 10 { 11 std::cout<<"load fun error\n"; 12 return -1; 13 } 14 fun();生成和使用靜態(tài)庫
生成靜態(tài)庫
新建項目--win32項目--填寫項目名--確定--下一步--應(yīng)用程序類型:選擇靜態(tài)庫
靜態(tài)庫項目沒有main函數(shù),也沒有像dll項目中的dllmain。
創(chuàng)建項目后添加.h文件,添加相應(yīng)的導(dǎo)出函數(shù)、變量或類,如下所示
1 #ifndef _MYLIB_H_ 2 #define _MYLIB_H_ 3 4 void fun(int a); 5 6 extern int k; 7 8 class testclass 9 { 10 public: 11 testclass(); 12 void print(); 13 }; 14 15 #endif.cpp文件如下
1 #include "stdafx.h" 2 #include "lib.h" 3 #include <iostream> 4 5 void fun(int a) 6 { 7 std::cout<<a<<"lib gen\n"; 8 } 9 10 int k = 222; 11 12 testclass::testclass() 13 { 14 std::cout<<"123\n"; 15 } 16 17 void testclass::print() 18 { 19 std::cout<<"this is testcalss\n"; 20 }編譯工程后就會生成一個.lib文件
使用靜態(tài)庫
需要.h文件,lib文件
(1)設(shè)置項目屬性--vc++目錄--庫目錄為lib所在的路徑
(2)將lib添加到項目屬性--鏈接器--輸入--附加依賴項(或者直接在源代碼中加入#pragma comment(lib, “**.lib”))
(3)在源文件中添加.h頭文件
然后就像平常一樣調(diào)用普通函數(shù)、類、變量,舉例如下:
1 #include <iostream> 2 #include "lib.h" 3 4 #pragma comment(lib, "lib.lib") 5 6 int main() 7 { 8 fun(4); 9 std::cout<<k<<std::endl; 10 testclass tc; 11 tc.print(); 12 return 0; 13 }?【版權(quán)聲明】轉(zhuǎn)載請注明出處?http://www.cnblogs.com/TenosDoIt/p/3203137.html
總結(jié)
以上是生活随笔為你收集整理的lib 和 dll 的区别、生成以及使用详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ || && 逻辑短路问题
- 下一篇: C++:vector中的resize()