資源描述:
《動(dòng)態(tài)鏈接庫(kù)詳解.docx》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫(kù)。
1、lib和dll的聯(lián)系首先我們來(lái)明白一個(gè)工程從創(chuàng)建到可執(zhí)行文件的過(guò)程:創(chuàng)建工程——編寫代碼——編譯——鏈接——可執(zhí)行文件。下一篇日記中會(huì)重點(diǎn)介紹VC的編譯與鏈接的過(guò)程,此文重點(diǎn)在講項(xiàng)目、dll與lib。我相信任何人肯定能從VC6.0的目錄下找到兩個(gè)文件夾lib與include。而include內(nèi)的都是大家熟悉的頭文件(如iostream.h、conio.h)等文件。這些頭文大家都是能夠查看與打開(kāi)的,就好比你寫的頭文件一樣,里面有很多的聲明。而且我敢肯定的是大家肯定找不到的是.cpp文件。你也許會(huì)好奇光有頭文件里這些類這些聲明,而沒(méi)有具體的實(shí)現(xiàn)的
2、話(c++一般都是在.h中寫類的一些接口,而實(shí)現(xiàn)的部分是在.cpp文件中),我們是如何來(lái)用它的呢?這就和你的編譯器有很大的關(guān)系了。不同的編譯器處理的方式不通。就拿VC6.0來(lái)說(shuō):假設(shè)你有3個(gè).cpp文件(a.cpp、b.cpp、c.pp)。在編譯器預(yù)處理的時(shí)候它會(huì)把頭文件(.h)的內(nèi)容都會(huì)插入到你的對(duì)應(yīng)的.cpp文件中。如a.cpp文件中有#include、#include。則預(yù)處理的時(shí)候會(huì)把a(bǔ).h文件的內(nèi)容都復(fù)制到了a.cpp文件中,當(dāng)然還有include文件夾下的iostream.h內(nèi)容,當(dāng)然iostream
3、.h文件中的,,,中的內(nèi)容也會(huì)通過(guò)遞歸的方式加入進(jìn)來(lái)(當(dāng)然不是都不是整個(gè).h文件的內(nèi)容都一定要加入進(jìn)去的,預(yù)處理做的事情不只有這么簡(jiǎn)單,如想了解可以去查資料,這里只是不必增加復(fù)雜度,你暫時(shí)可以理解為都加入進(jìn)去了)。然后每個(gè).cpp文件其實(shí)可以理解為一個(gè)編譯的單元,可以分別編譯的。(這樣的做法,很明顯可以提高速度,如果你每改一個(gè)文件,所以文件都要重新都編譯下的話,所耗的時(shí)間是相當(dāng)?shù)捏@人的,所以c++把每個(gè)編譯單元都獨(dú)立出來(lái)編譯成obj文件,然后在通過(guò)鏈接成為一個(gè)可執(zhí)
4、行文件。)。通過(guò)編譯每個(gè)cpp文件它會(huì)產(chǎn)生一個(gè).obj文件。如上面的三個(gè)文件它會(huì)產(chǎn)生a.obj,b.obj,c.obj文件(還有一些其他文件,但你不需要了解,你需要記住只是這里說(shuō)的是VC6.0的編譯器)。這里面都是2進(jìn)制的代碼,每個(gè)obj文件它所含的內(nèi)容除了編譯后的產(chǎn)生的數(shù)據(jù)和代碼外,它還必須含有3個(gè)表:未解決符號(hào)表、導(dǎo)出符號(hào)表、地址重定向表。先別著急了解這3個(gè)表的含義。我們來(lái)通過(guò)程序了解:假設(shè)有:A.cpp:extern?intm_a;???????????//聲明變量avoidset(){ m_a=6;}B.cpp:intm_a?=
5、6;???????????????????//全局變量avoidadd(){ m_a++;};編譯這兩個(gè)文件產(chǎn)生了A.obj、B.obj文件??蛇@些文件是分別編譯的,我們?cè)趺粗繟.cpp中的值的大小呢?這就是表的作用了!.obj內(nèi)除了自己數(shù)據(jù)外,還有的導(dǎo)入符號(hào)表和未解決符號(hào)表就是告訴編譯器我能提供什么東西,我還需要什么東西。地址重定向表是解決地址沖突的,這里不做深究。如:A.obj的導(dǎo)出符號(hào)表中有m_a、set()。未解決表中沒(méi)有。B.obj的導(dǎo)出符號(hào)表中有add()。未解決表中有m_a;這樣以后再鏈接的時(shí)候,編譯器去找B.obj需要
6、的m_a的時(shí)候找到了唯一的A.obj中導(dǎo)出的m_a。(下一章的內(nèi)部連接和外部連接會(huì)更深入的了解)。這樣然后整合到一個(gè).exe(含main方法的那個(gè)cpp文件)文件中成為一個(gè)可執(zhí)行文件。好了現(xiàn)在說(shuō)完這些,你就會(huì)更加清楚的去了解lib與dll內(nèi)。lib分為靜態(tài)的鏈接庫(kù)和動(dòng)態(tài)的鏈接庫(kù),這些也都是2進(jìn)制代碼。(1)我們不是在VC的lib文件夾下看到了很多的lib文件嗎?這些是靜態(tài)的鏈接庫(kù),你其實(shí)可以把它理解為一個(gè)項(xiàng)目(項(xiàng)文件含有的obj文件的總和,如為完成某個(gè)功能,一般不是只需要一個(gè)cpp文件就能完成的,而每個(gè)cpp在編譯后都會(huì)產(chǎn)生obj)的obj文
7、件(為方便理解才這么所,當(dāng)然不可能這么簡(jiǎn)單)。當(dāng)然這些就是Microsoft的VC6.0的源文件發(fā)布后能提供的東西。所以我們自己編寫的代碼中的頭文件需要的東西,可以對(duì)應(yīng)的lib找到對(duì)應(yīng)的入口。如iostream.h中的iostream(constiostream&)函數(shù)需要的東西可以從lib中找到入口,如果某個(gè)對(duì)應(yīng)lib里的導(dǎo)出符號(hào)表提供了iostream(constiostream&)函數(shù)的入口,我們就調(diào)用這lib中的iostream(constiostream&)具體實(shí)現(xiàn)(lib里的2進(jìn)制代碼)。(2)而使用動(dòng)態(tài)鏈接中的lib,不是obj
8、文件的集合,即里面不會(huì)有實(shí)際的實(shí)現(xiàn),它只是提供動(dòng)態(tài)鏈接到dll(后面有說(shuō)到它)所需要的信息,這種lib可以在編譯一個(gè)dll工程時(shí)由編譯器生成。所有你寫的代碼是結(jié)合了