VS2013动态库文件的创建及其使用详解
一、VS2013動(dòng)態(tài)庫(kù)文件的創(chuàng)建
1、新建項(xiàng)目,win32,win32項(xiàng)目,輸入項(xiàng)目名稱(chēng),例如MakeDll。
?
2、”確定“——”下一步“,選擇”DLL“選項(xiàng),再點(diǎn)”完成“:
?
3、菜單欄選擇”項(xiàng)目“——>”添加新項(xiàng)“,來(lái)創(chuàng)建頭文件MakeDll.h。
在MakeDll.h中輸入以下例子代碼:
1 #ifdef DLL_API//如果已經(jīng)定義就什么都不做 2 //nothing to do 3 #else //否則定義DLL_API 4 #define DLL_API __declspec(dllexport) //_declspec(dllexport):導(dǎo)出標(biāo)志 5 #endif 6 #include <iostream> 7 using namespace std; 8 DLL_API int add(int a, int b);//導(dǎo)出單獨(dú)的函數(shù) 9 class DLL_API Point //導(dǎo)出類(lèi),其自身所有函數(shù)都將被導(dǎo)出,可單獨(dú)對(duì)某些類(lèi)函數(shù)導(dǎo)出 10 { 11 private: 12 float x, y; 13 public: 14 Point(); 15 void SetPoint(float a, float b); 16 void DisPlay(); 17 };?
4、創(chuàng)建cpp文件:MakeDll.cpp。
在MakeDll.cpp中輸入以下例子代碼:
1 #include "MakeDll.h" 2 3 int add(int a, int b) 4 { 5 return a + b; 6 } 7 8 Point::Point() 9 { 10 x = 0.0f; 11 y = 0.0f; 12 } 13 14 void Point::SetPoint(float a, float b) 15 { 16 x = a; 17 y = b; 18 } 19 void Point::DisPlay() 20 { 21 cout << "x=" << x << endl; 22 cout << "y=" << y << endl; 23 }?
5、菜單欄選擇”生成——>生成解決方案“。
此時(shí)在MakeDll項(xiàng)目所在目錄下的Debug目錄下的文件有MakeDll.dll和MakeDll.lib了。生成動(dòng)態(tài)鏈接庫(kù)文件OK。
?
二、使用剛才創(chuàng)建的動(dòng)態(tài)庫(kù)
1、新建項(xiàng)目——win32控制臺(tái)應(yīng)用程序,命名為UseDll,并創(chuàng)建一個(gè)lib文件,將MakeDll.lib引導(dǎo)庫(kù)放進(jìn)去,
并將MakeDll.dll放進(jìn)debug下,編譯器會(huì)自動(dòng)搜素到這個(gè)文件,當(dāng)然可以放在系統(tǒng)目錄下。
2、告訴編譯器頭文件MakeDll.h的位置(見(jiàn)包含目錄)、引導(dǎo)庫(kù)位置(見(jiàn)庫(kù)目錄)及其名字(見(jiàn)附加依賴項(xiàng))。注意,以下是添加后的顯示結(jié)果。
圖.包含目錄的設(shè)置
圖.庫(kù)目錄的設(shè)置
?
圖.附加依賴項(xiàng)的設(shè)置
?
3、最后,動(dòng)態(tài)庫(kù)的測(cè)試程序如下,測(cè)試程序需要引用頭文件:
1 #include <iostream> 2 #include "MakeDll.h" 3 using namespace std; 4 5 int main() 6 { 7 int a = 10; 8 int b = 2; 9 int c = add(a, b); 10 cout << c << endl; 11 Point p1, p2; 12 p2.SetPoint(5.6f, 7.8f); 13 p1.DisPlay(); 14 p2.DisPlay(); 15 getchar(); 16 return 0; 17 }運(yùn)行結(jié)果:
至此測(cè)試成功!
?
三、h頭文件 .lib庫(kù)文件 .dll動(dòng)態(tài)鏈接庫(kù)文件關(guān)系
.h頭文件是編譯時(shí)必須的,lib是鏈接時(shí)需要的,dll是運(yùn)行時(shí)需要的。
附加依賴項(xiàng)添加的是.lib而不是.dll,若生成了DLL,則肯定也生成了LIB文件。
.h .lib .dll三者的關(guān)系:
H文件的作用:聲明函數(shù)接口
DLL文件作用:函數(shù)可執(zhí)行代碼
LIB文件作用:當(dāng)我們?cè)谧约旱某绦蛑幸昧艘粋€(gè)H文件里的函數(shù),鏈接器怎么知道該調(diào)用哪個(gè)DLL文件呢?這就是LIB文件的作用了。它告訴鏈接器調(diào)用的函數(shù)在哪個(gè)DLL中,函數(shù)執(zhí)行代碼在DLL中的什么位置,這也就是為什么需要附加依賴項(xiàng).LIB文件,它起到橋梁的作用。
如果是生成靜態(tài)庫(kù)文件,則沒(méi)有DLL,只有l(wèi)ib,這時(shí)函數(shù)可執(zhí)行代碼部分也在lib文件中。
目前以lib后綴的庫(kù)有兩種,一種為靜態(tài)鏈接庫(kù)(Static Libary,以下簡(jiǎn)稱(chēng)“靜態(tài)庫(kù)”),另一種為動(dòng)態(tài)連接庫(kù)(DLL,以下簡(jiǎn)稱(chēng)“動(dòng)態(tài)庫(kù)”)的導(dǎo)入庫(kù)(Import Libary,以下簡(jiǎn)稱(chēng)“導(dǎo)入庫(kù)”)。靜態(tài)庫(kù)是一個(gè)或者多個(gè)obj文件的打包,所以有人干脆把從obj文件生成lib的過(guò)程稱(chēng)為Archive,即合并到一起。比如你鏈接一個(gè)靜態(tài)庫(kù),如果其中有錯(cuò),它會(huì)準(zhǔn)確的找到是哪個(gè)obj有錯(cuò),即靜態(tài)lib只是殼子。動(dòng)態(tài)庫(kù)一般會(huì)有對(duì)應(yīng)的導(dǎo)入庫(kù),方便程序靜態(tài)載入動(dòng)態(tài)鏈接庫(kù),否則你可能就需要自己LoadLibary調(diào)入DLL文件,然后再手工GetProcAddress獲得對(duì)應(yīng)函數(shù)了。有了導(dǎo)入庫(kù),你只需要鏈接導(dǎo)入庫(kù)后按照頭文件函數(shù)接口的聲明調(diào)用函數(shù)就可以了。導(dǎo)入庫(kù)和靜態(tài)庫(kù)的區(qū)別很大,他們實(shí)質(zhì)是不一樣的東西。靜態(tài)庫(kù)本身就包含了實(shí)際執(zhí)行代碼、符號(hào)表等等,而對(duì)于導(dǎo)入庫(kù)而言,其實(shí)際的執(zhí)行代碼位于動(dòng)態(tài)庫(kù)中,導(dǎo)入庫(kù)只包含了地址符號(hào)表等,確保程序找到對(duì)應(yīng)函數(shù)的一些基本地址信息。
一般的動(dòng)態(tài)庫(kù)程序有l(wèi)ib文件和dll文件。lib文件是必須在編譯期就連接到應(yīng)用程序中的,而dll文件是運(yùn)行期才會(huì)被調(diào)用的。如果有dll文件,那么對(duì)應(yīng)的lib文件一般是一些索引信息,具體的實(shí)現(xiàn)在dll文件中。如果只有l(wèi)ib文件,那么這個(gè)lib文件是靜態(tài)編譯出來(lái)的,索引和實(shí)現(xiàn)都在其中。
靜態(tài)編譯的lib文件的好處:給用戶安裝時(shí)就不需要再掛動(dòng)態(tài)庫(kù)了。但也有缺點(diǎn),就是導(dǎo)致應(yīng)用程序比較大,而且失去了動(dòng)態(tài)庫(kù)的靈活性,在版本升級(jí)時(shí),同時(shí)要發(fā)布新的應(yīng)用程序才行。
在動(dòng)態(tài)庫(kù)的情況下,有兩個(gè)文件,而一個(gè)是引入庫(kù)(.LIB)文件,一個(gè)是DLL文件,引入庫(kù)文件包含被DLL導(dǎo)出的函數(shù)的名稱(chēng)和位置,DLL包含實(shí)際的函數(shù)和數(shù)據(jù),應(yīng)用程序使用LIB文件鏈接到所需要使用的DLL文件,庫(kù)中的函數(shù)和數(shù)據(jù)并不復(fù)制到可執(zhí)行文件中,因此在應(yīng)用程序的可執(zhí)行文件中,存放的不是被調(diào)用的函數(shù)代碼,而是DLL中所要調(diào)用的函數(shù)的內(nèi)存地址,這樣當(dāng)一個(gè)或多個(gè)應(yīng)用程序運(yùn)行是再把程序代碼和被調(diào)用的函數(shù)代碼鏈接起來(lái),從而節(jié)省了內(nèi)存資源。從上面的說(shuō)明可以看出,DLL和.LIB文件必須隨應(yīng)用程序一起發(fā)行,否則應(yīng)用程序?qū)?huì)產(chǎn)生錯(cuò)誤。
在VC中加載LIB文件的幾種方法:
? ①LIB文件直接加入到工程文件列表中?
在VC中打開(kāi)File View一頁(yè),選中工程名,單擊鼠標(biāo)右鍵,然后選中"Add Files to Project"菜單,在彈出的文件對(duì)話框中選中要加入DLL的LIB文件即可。?
②設(shè)置工程的 Project Settings來(lái)加載DLL的LIB文件?
之前的步驟提到過(guò),這里不再提。
③通過(guò)程序代碼的方式?
加入預(yù)編譯指令#pragma comment (lib,"*.lib"),這種方法優(yōu)點(diǎn)是可以利用條件預(yù)編譯指令鏈接不同版本的LIB文件。因?yàn)?#xff0c;在Debug方式下,產(chǎn)生的LIB文件是Debug版本,如Regd.lib;在Release方式下,產(chǎn)生的LIB文件是Release版本,如Regr.lib。?
當(dāng)應(yīng)用程序?qū)LL的LIB文件加載后,還需要把DLL對(duì)應(yīng)的頭文件(*.h)包含到其中,在這個(gè)頭文件中給出了DLL中定義的函數(shù)原型,然后聲明。
?
四、動(dòng)態(tài)鏈接庫(kù)的優(yōu)點(diǎn)
因?yàn)閯?dòng)態(tài)鏈接庫(kù)是將功能封裝在一起的模塊,因此,與將代碼直接寫(xiě)入調(diào)用模塊中相比,它不僅可以提高程序的復(fù)用,減少代碼開(kāi)發(fā)工作量,同時(shí)使得功能更新更方便。除了這些模塊化帶來(lái)的優(yōu)點(diǎn)外,動(dòng)態(tài)鏈接庫(kù)的工作方式也決定了它先天具有比靜態(tài)鏈接更多的優(yōu)點(diǎn),如下所述。
1、節(jié)約內(nèi)存和減少交換:當(dāng)應(yīng)用程序使用動(dòng)態(tài)鏈接時(shí),多個(gè)進(jìn)程可以同步使用一個(gè)DLL共享內(nèi)存中DLL的單個(gè)副本。相比之下,當(dāng)應(yīng)用程序使用靜態(tài)鏈接庫(kù)時(shí),Windows必須為每個(gè)應(yīng)用程序裝載一個(gè)庫(kù)代碼的副本到內(nèi)存中。
2、節(jié)約磁盤(pán)空間:當(dāng)應(yīng)用程序使用動(dòng)態(tài)鏈接時(shí),多個(gè)應(yīng)用程序可以共享磁盤(pán)上單個(gè)DLL副本。相比之下,當(dāng)應(yīng)用程序使用靜態(tài)鏈接庫(kù)時(shí),每個(gè)應(yīng)用程序要將庫(kù)代碼作為獨(dú)立的副本鏈接到可執(zhí)行鏡像中。
3、當(dāng)DLL中的函數(shù)修改時(shí),只要函數(shù)參數(shù)、調(diào)用規(guī)定和返回值沒(méi)有改變,使用DLL的應(yīng)用程序不需要重新編譯或鏈接。而靜態(tài)鏈接的函數(shù)改變時(shí),需要應(yīng)用程序重新鏈接。
4、支持多語(yǔ)言編程:只要應(yīng)用程序遵循相同的調(diào)用規(guī)范,則使用不同編程語(yǔ)言編寫(xiě)的程序可以調(diào)用相同的DLL函數(shù)。程序和DLL函數(shù)必須兼容:函數(shù)定義的參數(shù)入棧順序,函數(shù)或應(yīng)用程序誰(shuí)來(lái)負(fù)責(zé)清理堆棧,參數(shù)是否傳入寄存器中等方面必須兼容。
5、輕松的創(chuàng)建中間版本:通過(guò)將資源放入DLL中,使得創(chuàng)建應(yīng)用程序的中間版本非常簡(jiǎn)單。如可以將應(yīng)用程序的每個(gè)語(yǔ)言版本的字符串放到單獨(dú)的一個(gè)資源DLL中,并為不同的語(yǔ)言版本裝載合適的資源DLL就可以了。
雖然使用DLL有諸多的優(yōu)點(diǎn),但是也需要格外注意使用DLL的缺點(diǎn)。即調(diào)用DLL的應(yīng)用程序不是獨(dú)立的,程序的運(yùn)行依賴于所使用的DLL是否存在。
?
轉(zhuǎn)自http://blog.csdn.net/ebowtang/article/details/38499927
總結(jié)
以上是生活随笔為你收集整理的VS2013动态库文件的创建及其使用详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: VS2013建立C++ dll库文件
- 下一篇: CString与string、char*