轉:.h標頭檔 .lib庫檔案 .dll動態連結程式庫檔案關係

來源:互聯網
上載者:User

.h標頭檔是編譯時間必須的,lib是連結時需要的,dll是運行時需要的。

附加依賴項的是.lib不是.dll,若產生了DLL,則肯定也產生 LIB檔案。如果要完成原始碼的編譯和連結,有標頭檔和lib就夠了。如果也使動態串連的程式運行起來,有dll就夠了。在開發和調試階段,當然最好都有。

.h .lib .dll三者的關係是:

H檔案作用是:聲明函數介面

DLL檔案作用是: 函數可執行代碼

當我們在自己的程式中引用了一個H檔案裡的函數,編鏈器怎麼知道該調用哪個DLL檔案呢?這就是LIB檔案的作用: 告訴連結器 調用的函數在哪個DLL中,函數執行代碼在DLL中的什麼位置,這也就是為什麼需要附加依賴項 .LIB檔案,它起到橋樑的作用。如果產生靜態庫檔案,則沒有DLL ,只有lib,這時函數可執行代碼部分也在lib檔案中

目前以lib尾碼的庫有兩種,一種為靜態連結庫(Static Libary,以下簡稱“靜態庫”),另一種為動態串連庫(DLL,以下簡稱“動態庫”)的匯入庫(Import Libary,以下簡稱“匯入庫”)。靜態庫是一個或者多個obj檔案的打包,所以有人乾脆把從obj檔案產生lib的過程稱為Archive,即合并到一起。比如你連結一個靜態庫,如果其中有錯,它會準確的找到是哪個obj有錯,即靜態lib只是殼子。動態庫一般會有對應的匯入庫,方便程式靜態載入動態連結程式庫,否則你可能就需要自己LoadLibary調入DLL檔案,然後再手工GetProcAddress獲得對應函數了。有了匯入庫,你只需要連結匯入庫後按照標頭檔函數介面的聲明調用函數就可以了。匯入庫和靜態庫的區別很大,他們實質是不一樣的東西。靜態庫本身就包含了實際執行代碼、符號表等等,而對於匯入庫而言,其實際的執行代碼位於動態庫中,匯入庫只包含了地址符號表等,確保程式找到對應函數的一些基本地址資訊。

一般的動態庫程式有lib檔案和dll檔案。lib檔案是必須在編譯期就串連到應用程式中的,而dll檔案是運行期才會被調用的。如果有dll檔案,那麼對應的lib檔案一般是一些索引資訊,具體的實現在dll檔案中。如果只有lib檔案,那麼這個lib檔案是靜態編譯出來的,索引和實現都在其中。靜態編譯的lib檔案有好處:給使用者安裝時就不需要再掛動態庫了。但也有缺點,就是導致應用程式比較大,而且失去了動態庫的靈活性,在版本升級時,同時要發布新的應用程式才行。在動態庫的情況下,有兩個檔案,而一個是引入庫(.LIB)檔案,一個是DLL檔案,引入庫檔案包含被DLL匯出的函數的名稱和位置,DLL包含實際的函數和資料,應用程式使用LIB檔案連結到所需要使用的DLL檔案,庫中的函數和資料並不複製到可執行檔中,因此在應用程式的可執行檔中,存放的不是被調用的函數代碼,而是DLL中所要調用的函數的記憶體位址,這樣當一個或多個應用程式運行是再把程式碼和被調用的函數代碼連結起來,從而節省了記憶體資源。從上面的說明可以看出,DLL和.LIB檔案必須隨應用程式一起發行,否則應用程式將會產生錯誤。

-------------------------------------------------------------------------------------

靜態連結庫(Lib)與動態連結程式庫(DLL)的區別 

     靜態串連庫就是把(lib)檔案中用到的函數代碼直接連結進目標程式,程式啟動並執行時候不再需要其它的庫檔案;動態連結就是把調用的函數所在檔案模組(DLL)和調用函數在檔案中的位置等資訊連結進目標程式,程式啟動並執行時候再從DLL中尋找相應函數代碼,因此需要相應DLL檔案的支援。

靜態連結庫與動態連結程式庫都是共用代碼的方式,如果採用靜態連結庫,則無論你願不願意,lib 中的指令都全部被直接包含在最終產生的 EXE 檔案中了。但是若使用 DLL,該 DLL 不必被包含在最終 EXE 檔案中,EXE 檔案執行時可以“動態”地引用和卸載這個與 EXE 獨立的 DLL 檔案。靜態連結庫和動態連結程式庫的另外一個區別在於靜態連結庫中不能再包含其他的動態連結程式庫或者靜態庫,而在動態連結程式庫中還可以再包含其他的動態或靜態連結庫。

“每一個lib檔案就是若干函數(假設只有函數)的定義” 
lib庫有兩種,一種是包含了函數所在DLL檔案和檔案中函數位置的資訊,稱為匯出庫;一種是包含函數代碼本身,一般現有的DLL,用的是前一種庫;以前在DOS下的TC/BC等,是後一種庫。包含函數原型聲明的,是標頭檔(.h)。 

“通過#include包含這些函式宣告的標頭檔後,我們的應用程式就可以使用lib檔案中的函數”

還要指定編譯器連結相應的庫檔案。在IDE環境下,一般是一次指定所有用到的庫檔案,編譯器自己尋找每個模組需要的庫;在命令列編譯環境下,需要指定每個模組調用的庫。 

“那他和直接給出那個函數定義的檔案,比如.cpp檔案,和標頭檔有什麼區別,靜態連結庫有什麼用” 
cpp檔案是原始碼,庫檔案是編譯後的二進位代碼,比如你可以調用Windows的API,但是不能看到其原始碼一樣。 

“還有不明白的是,靜態連結庫中的lib檔案只要用到,則整個lib檔案的內容都放進了exe檔案中,那它是被編譯進去還是連結的時候串連進去的呢?” 
是在連結的時候將lib連結到目標代碼中。

轉自:http://www.cnblogs.com/zcshan/archive/2010/12/03/1895605.html 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.