如果對Linux下靜態(tài)鏈接庫和動態(tài)鏈接庫感興趣,請狂點(diǎn)擊 -->
你懂的
一,概念
1)靜態(tài)鏈接庫就是你使用的.lib文件,庫中得代碼最后需要連接到你的可執(zhí)行文件中去,所以靜態(tài)連接的可執(zhí)行文件一般比較大一些。
在靜態(tài)庫情況下,函數(shù)和數(shù)據(jù)被編譯進(jìn)一個(gè)二進(jìn)制文件(通常擴(kuò)展名為*.lib),Visual C++的編譯器在鏈接過程中將從靜態(tài)庫中恢復(fù)這些函數(shù)和數(shù)據(jù)并把他們和應(yīng)用程序中的其他模塊組合在一起生成可執(zhí)行文件。這個(gè)過程稱為"靜態(tài)鏈接",此時(shí)因?yàn)閼?yīng)用程序所需的全部內(nèi)容都是從庫中復(fù)制了出來,所以
靜態(tài)庫本身并不需要與可執(zhí)行文件一起發(fā)行
。
編程使用: 使用lib需注意兩個(gè)文件:
(1).h頭文件,包含lib中說明輸出的類或符號原型或數(shù)據(jù)結(jié)構(gòu)。應(yīng)用程序調(diào)用lib時(shí),需要將該文件包含入應(yīng)用程序的源文件中。
(2).lib文件,見上面。
2)Dynamic Link Library 的縮寫形式,DLL是一個(gè)包含可由多個(gè)程序同時(shí)使用的代碼和數(shù)據(jù)的庫,DLL不是 可執(zhí)行 文件。動態(tài)鏈接提供了一種方法,使進(jìn)程可以調(diào)用不屬于其可執(zhí)行代碼的函數(shù)。函數(shù)的可執(zhí)行代碼位于一個(gè) DLL 中,該 DLL 包含一個(gè)或多個(gè)已被編譯、鏈接并與使用它們的進(jìn)程分開存儲的函數(shù)。DLL 還有助于共享數(shù)據(jù)和資源。多個(gè) 應(yīng)用程序 可同時(shí)訪問 內(nèi)存 中單個(gè)DLL 副本的內(nèi)容。DLL 是一個(gè)包含可由多個(gè)程序同時(shí)使用的代碼和數(shù)據(jù)的庫。
DLL舉例
ActiveX 控件 (.ocx) 文件:示例是日歷控件,它使您可以從日歷中選擇日期。 ·
控制面板 (.cpl) 文件 :cpl 文件的一個(gè)示例是位于控制面板中的項(xiàng)。每個(gè)項(xiàng)都是一個(gè)專用 DLL。
編程使用;
使用dll需注意三個(gè)文件:
(1).h頭文件,包含dll中說明輸出的類或符號原型或數(shù)據(jù)結(jié)構(gòu)的.h文件。應(yīng)用程序調(diào)用dll時(shí),需要將該文件包含入應(yīng)用程序的源文件中。
(2).LIB文件,是dll在編譯、鏈接成功之后生成的文件,作用是當(dāng)其他應(yīng)用程序調(diào)用dll時(shí),需要將該文件引入應(yīng)用程序,否則產(chǎn)生錯誤。
如果不想用lib文件或者沒有l(wèi)ib文件,可以用WIN32 API函數(shù)LoadLibrary、GetProcAddress裝載。
(3).dll文件,真正的可執(zhí)行文件,開發(fā)成功后的應(yīng)用程序在發(fā)布時(shí),只需要有.exe文件和.dll文件,并不需要.lib文件和.h頭文件。
二,初步認(rèn)識
共有兩種庫:
一種是lib包含了函數(shù)所在的DLL文件和文件中函數(shù)位置的信息(入口),代碼由運(yùn)行時(shí)加載在進(jìn)程空間中的DLL提供,稱為動態(tài)鏈接庫dynamic link library。
一種是lib包含函數(shù)代碼本身,在編譯時(shí)直接將代碼加入程序當(dāng)中,稱為靜態(tài)鏈接庫static link library。
共有兩種鏈接方式:
動態(tài)鏈接使用動態(tài)鏈接庫,允許可執(zhí)行模塊(.dll文件或.exe文件)僅包含在運(yùn)行時(shí)定位DLL函數(shù)的可執(zhí)行代碼所需的信息。
靜態(tài)鏈接使用靜態(tài)鏈接庫,鏈接器從靜態(tài)鏈接庫lib獲取所有被引用函數(shù),并將庫同代碼一起放到可執(zhí)行文件中。
三,關(guān)于lib和dll的區(qū)別如下:
(1)lib是編譯時(shí)用到的,dll是運(yùn)行時(shí)用到的。如果要完成
源代碼的編譯,只需要lib
;如果要使
動態(tài)鏈接的程序運(yùn)行起來,只需要dll
。
(2)如果有dll文件,那么lib一般是一些
索引信息,記錄了dll中函數(shù)的入口和位置,dll中是函數(shù)的具體內(nèi)容
;如果
只有
lib文件,那么這個(gè)lib文件是
靜態(tài)編譯出來的,索引和實(shí)現(xiàn)都在其中
。使用靜態(tài)編譯的lib文件,在運(yùn)行程序時(shí)不需要再掛動態(tài)庫,缺點(diǎn)是導(dǎo)致應(yīng)用程序比較大,而且失去了動態(tài)庫的靈活性,發(fā)布新版本時(shí)要發(fā)布新的應(yīng)用程序才行。
(3)
動態(tài)鏈接
的情況下,有兩個(gè)文件:一個(gè)是LIB文件,一個(gè)是DLL文件。
LIB包含被DLL導(dǎo)出的函數(shù)名稱和位置
,
DLL包含實(shí)際的函數(shù)和數(shù)據(jù)
,應(yīng)用程序使用LIB文件鏈接到DLL文件。在應(yīng)用程序的可執(zhí)行文件中,存放的不是被調(diào)用的函數(shù)代碼,而是DLL中相應(yīng)函數(shù)代碼的地址,從而節(jié)省了內(nèi)存資源。DLL和LIB文件必須隨應(yīng)用程序一起發(fā)行,否則應(yīng)用程序會產(chǎn)生錯誤。如果不想用lib文件或者沒有l(wèi)ib文件,可以用WIN32 API函數(shù)LoadLibrary、GetProcAddress裝載。
使用lib的方法:
靜態(tài)lib中,一個(gè)lib文件實(shí)際上是任意個(gè)obj文件的集合,obj文件是cpp文件編譯生成的。在編譯這種靜態(tài)庫工程時(shí),根本不會遇到鏈接錯誤;即使有錯,也只會在使用這個(gè)lib的EXT文件或者DLL工程里暴露出來。
在VC中新建一個(gè)static library類型的工程Lib,加入test.cpp文件和test.h文件(頭文件內(nèi)包括函數(shù)聲明),然后編譯,就生成了Lib.lib文件。
別的工程要使用這個(gè)lib有兩種方式:
(1)在project->link->Object/Library Module中加入Lib.lib文件(先查詢工程目錄,再查詢系統(tǒng)Lib目錄);或者在源代碼中加入指令#pragma comment(lib, “Lib.lib”)。
(2)將Lib.lib拷入工程所在目錄,或者執(zhí)行文件生成的目錄,或者系統(tǒng)Lib目錄中。
(3)加入相應(yīng)的頭文件test.h。
使用DLL的方法:
使用動態(tài)鏈接中的lib,不是obj文件的集合,即里面不會有實(shí)際的實(shí)現(xiàn),它只是提供動態(tài)鏈接到DLL所需要的信息,這種lib可以在編譯一個(gè)DLL工程時(shí)由編譯器生成。
創(chuàng)建DLL工程的方法(略)。
(1)隱式鏈接
第一種方法是:通過project->link->Object/Library Module中加入.lib文件(或者在源代碼中加入指令#pragma comment(lib, “Lib.lib”)),并將.dll文件置入工程所在目錄,然后添加對應(yīng)的.h頭文件。
#include "stdafx.h" #include "DLLSample.h" #pragma comment(lib, "DLLSample.lib") //你也可以在項(xiàng)目屬性中設(shè)置庫的鏈接 int main() { TestDLL(123); //dll中的函數(shù),在DllSample.h中聲明 return(1); }
(2)顯式鏈接
需要函數(shù)指針和WIN32 API函數(shù)LoadLibrary、GetProcAddress裝載,使用這種載入方法,
不需要.lib文件和.h頭文件,只需要.dll文件即可
(將.dll文件置入工程目錄中)。
#include <iostream> #include <windows.h> //使用函數(shù)和某些特殊變量 typedef void (*DLLFunc)(int); int main() { DLLFunc dllFunc; HINSTANCE hInstLibrary = LoadLibrary("DLLSample.dll"); if (hInstLibrary == NULL) { FreeLibrary(hInstLibrary); } dllFunc = (DLLFunc)GetProcAddress(hInstLibrary, "TestDLL"); if (dllFunc == NULL) { FreeLibrary(hInstLibrary); } dllFunc(123); std::cin.get(); FreeLibrary(hInstLibrary); return(1); }
LoadLibrary函數(shù)利用一個(gè)名稱作為參數(shù),獲得DLL的實(shí)例(HINSTANCE類型是實(shí)例的句柄),通常調(diào)用該函數(shù)后需要查看一下函數(shù)返回是否成功,如果不成功則返回NULL(句柄無效),此時(shí)調(diào)用函數(shù)FreeLibrary釋放DLL獲得的內(nèi)存。
GetProcAddress函數(shù)利用DLL的句柄和函數(shù)的名稱作為參數(shù),返回相應(yīng)的函數(shù)指針,同時(shí)必須使用強(qiáng)轉(zhuǎn);判斷函數(shù)指針是否為NULL,如果是則調(diào)用函數(shù)FreeLibrary釋放DLL獲得的內(nèi)存。此后,可以使用函數(shù)指針來調(diào)用實(shí)際的函數(shù)。
最后要記得使用FreeLibrary函數(shù)釋放內(nèi)存。
注意:應(yīng)用程序如何找到DLL文件?
使用LoadLibrary顯式鏈接,那么在函數(shù)的參數(shù)中可以指定DLL文件的完整路徑;如果不指定路徑,或者進(jìn)行隱式鏈接,Windows將遵循下面的搜索順序來定位DLL:
(1)包含EXE文件的目錄
(2)工程目錄
(3)Windows系統(tǒng)目錄
(4)Windows目錄
(5)列在Path環(huán)境變量中的一系列目錄
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
