版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
靜態(tài)鏈接庫(kù)和動(dòng)態(tài)鏈接庫(kù)郵箱:xinweil@2021/6/271
目錄概念定義12
靜態(tài)鏈接庫(kù)的創(chuàng)建3動(dòng)態(tài)鏈接庫(kù)的創(chuàng)建4
應(yīng)用實(shí)例2021/6/2721、概念定義2021/6/2731.1分別編譯與鏈接
大多數(shù)高級(jí)語(yǔ)言都支持分別編譯(compling),程序員可以顯式地把程序劃分為獨(dú)立的模塊或文件,然后由編譯器(compiler)對(duì)每個(gè)獨(dú)立部分分別進(jìn)行編譯。在編譯之后,由鏈接器(Linker)把這些獨(dú)立編譯單元鏈接(Linking)到一起。
鏈接方式有兩種:靜態(tài)鏈接、動(dòng)態(tài)鏈接。
2021/6/2741.2鏈接方式
靜態(tài)鏈接方式:在程序開(kāi)發(fā)中,將各種目標(biāo)模塊(.OBJ)文件、運(yùn)行時(shí)庫(kù)(.LIB)文件,以及已編譯的資源(.RES)文件鏈接在一起,以便創(chuàng)建Windows的.EXE文件。
動(dòng)態(tài)鏈接方式:在程序運(yùn)行時(shí),Windows把一個(gè)模塊中的函數(shù)調(diào)用鏈接到庫(kù)模塊中的實(shí)際函數(shù)上的過(guò)程。
2021/6/2751.2鏈接方式
靜態(tài)鏈接庫(kù)(簡(jiǎn)稱LIB)與動(dòng)態(tài)鏈接庫(kù)(簡(jiǎn)稱DLL)都是共享代碼的方式。如果使用靜態(tài)鏈接庫(kù)(也稱靜態(tài)庫(kù)),則無(wú)論你愿不愿意,.LIB文件中的指令都會(huì)被直接包含到最終生成的.EXE文件中。但是若使用.DLL文件,該.DLL文件中的代碼不必被包含在最終的.EXE文件中,.EXE文件執(zhí)行時(shí)可以“動(dòng)態(tài)”地載入和卸載這個(gè)與.EXE文件獨(dú)立的.DLL文件。2021/6/2761.3動(dòng)態(tài)鏈接方式鏈接一個(gè)DLL有兩種方式:
1、載入時(shí)動(dòng)態(tài)鏈接(Load-Time
Dynamic
Linking)
2、運(yùn)行時(shí)動(dòng)態(tài)鏈接(Run-Time
Dynamic
Linking)2021/6/277
1.3.1載入時(shí)動(dòng)態(tài)鏈接
使用載入時(shí)動(dòng)態(tài)鏈接,調(diào)用模塊可以像調(diào)用本模塊中的函數(shù)一樣直接使用導(dǎo)出函數(shù)名調(diào)用DLL中的函數(shù)。這需要在鏈接時(shí)將函數(shù)所在DLL的導(dǎo)入庫(kù)鏈接到可執(zhí)行文件中,導(dǎo)入庫(kù)向系統(tǒng)提供了載入DLL時(shí)所需的信息及用于定位DLL函數(shù)的地址符號(hào)。(相當(dāng)于注冊(cè),當(dāng)作API函數(shù)來(lái)使用,其實(shí)API函數(shù)就存放在系統(tǒng)DLL當(dāng)中)。2021/6/278
1.3.2運(yùn)行時(shí)動(dòng)態(tài)鏈接
使用運(yùn)行時(shí)動(dòng)態(tài)鏈接,運(yùn)行時(shí)可以通過(guò)LoadLibrary或LoadLibraryEx函數(shù)載入DLL。DLL載入后,模塊可以通過(guò)調(diào)用GetProcAddress獲取DLL函數(shù)的入口地址,然后就可以通過(guò)返回的函數(shù)指針調(diào)用DLL中的函數(shù)了。如此即可避免導(dǎo)入庫(kù)文件了。2021/6/279
1.4二者優(yōu)點(diǎn)及不足靜態(tài)鏈接庫(kù)的優(yōu)點(diǎn):(1)
代碼裝載速度快,執(zhí)行速度略比動(dòng)態(tài)鏈接庫(kù)快;
(2)
只需保證在開(kāi)發(fā)者的計(jì)算機(jī)中有正確的.LIB文件,在以二進(jìn)制形式發(fā)布程序時(shí)不需考慮在用戶的計(jì)算機(jī)上.LIB文件是否存在及版本問(wèn)題,可避免DLL地獄等問(wèn)題。2021/6/2710
1.4二者優(yōu)點(diǎn)及不足
動(dòng)態(tài)鏈接庫(kù)的優(yōu)點(diǎn)
(1)
更加節(jié)省內(nèi)存并減少頁(yè)面交換;
(2)
DLL文件與EXE文件獨(dú)立,只要輸出接口不變(即名稱、參數(shù)、返回值類型和調(diào)用約定不變),更換DLL文件不會(huì)對(duì)EXE文件造成任何影響,因而極大地提高了可維護(hù)性和可擴(kuò)展性;
(3)
不同編程語(yǔ)言編寫(xiě)的程序只要按照函數(shù)調(diào)用約定就可以調(diào)用同一個(gè)DLL函數(shù)。2021/6/2711
1.4二者優(yōu)點(diǎn)及不足不足之處
(1)
使用靜態(tài)鏈接生成的可執(zhí)行文件體積較大,包含相同的公共代碼,造成浪費(fèi);
(2)
使用動(dòng)態(tài)鏈接庫(kù)的應(yīng)用程序不是自完備的,它依賴的DLL模塊也要存在,如果使用載入時(shí)動(dòng)態(tài)鏈接,程序啟動(dòng)時(shí)發(fā)現(xiàn)DLL不存在,系統(tǒng)將終止程序并給出錯(cuò)誤信息。而使用運(yùn)行時(shí)動(dòng)態(tài)鏈接,系統(tǒng)不會(huì)終止,但由于DLL中的導(dǎo)出函數(shù)不可用,程序會(huì)加載失??;
(3)
使用動(dòng)態(tài)鏈接庫(kù)可能造成DLL地獄。2021/6/2712
1.4.1DLL
地獄DLL
地獄(DLL
Hell)是指因?yàn)橄到y(tǒng)文件被覆蓋而讓整個(gè)系統(tǒng)像是掉進(jìn)了地獄。簡(jiǎn)單地講,DLL地獄是指當(dāng)多個(gè)應(yīng)用程序試圖共享一個(gè)公用組件時(shí),如某個(gè)DLL或某個(gè)組件對(duì)象模型(COM)類,所引發(fā)的一系列問(wèn)題。2021/6/27131.4.1DLL
地獄最典型的情況是,某個(gè)應(yīng)用程序?qū)⒁惭b一個(gè)新版本的共享組件,而該組件與機(jī)器上的現(xiàn)有版本不向后兼容。雖然剛安裝的應(yīng)用程序運(yùn)行正常,但原來(lái)依賴前一版本共享組件的應(yīng)用程序也許已無(wú)法再工作。在某些情況下,問(wèn)題的起因更加難以預(yù)料。比如,當(dāng)用戶瀏覽某些web站點(diǎn)時(shí)會(huì)同時(shí)下載某個(gè)Microsoft
ActiveX控件。如果下載該控件,它將替換機(jī)器上原有的任何版本的控件。如果機(jī)器上的某個(gè)應(yīng)用程序恰好使用該控件,則很可能也會(huì)停止工作。
在許多情況下,用戶需要很長(zhǎng)時(shí)間才會(huì)發(fā)現(xiàn)應(yīng)用程序已停止工作。結(jié)果往往很難記起是何時(shí)的機(jī)器變化影響到了該應(yīng)用程序。2021/6/27142、靜態(tài)鏈接庫(kù)的創(chuàng)建2021/6/27152.1靜態(tài)鏈接庫(kù)的創(chuàng)建
在此通過(guò)一個(gè)實(shí)例來(lái)介紹靜態(tài)庫(kù)的創(chuàng)建與使用。在該實(shí)例中,我們實(shí)現(xiàn)將一個(gè)兩整數(shù)相加求和的函數(shù)封裝到靜態(tài)庫(kù)中供其他程序調(diào)用。2021/6/27162.1.1創(chuàng)建一個(gè)Win32控制臺(tái)應(yīng)用程序2021/6/27172.1.2選擇靜態(tài)庫(kù)應(yīng)用程序類型2021/6/27182.1.3新建一個(gè).h文件
需要給該靜態(tài)鏈接庫(kù)編寫(xiě)一個(gè)聲明頭文件Static.h,以便在鏈接時(shí)告知編譯該鏈接庫(kù)中的導(dǎo)出函數(shù)聲明。Static.h文件中的內(nèi)容:#ifndef_STATIC_H#define_STATIC_H//
防止該頭文件重復(fù)引用externintAdd(inta,intb);//聲明導(dǎo)出函數(shù)#endif2021/6/27192.1.4新建一個(gè).cpp文件
添加一個(gè)用于定義導(dǎo)出函數(shù)的源文件Static.cpp,編碼實(shí)現(xiàn)兩個(gè)整數(shù)相加的Add函數(shù)。源文件代碼如下:#include"static.h"intAdd(inta,intb){ returna+b;}2021/6/27202.1.5生成
點(diǎn)擊菜單命令,“工具”-“生成Static”。如果一切順利的話,就會(huì)在解決方案的“Debug”目錄中生成了名為“Static.lib”的靜態(tài)鏈接庫(kù)。2021/6/27212.2靜態(tài)鏈接庫(kù)的使用
新建一個(gè)Win32控制臺(tái)應(yīng)用程序空項(xiàng)目UseLIB。程序主文件名為UseLIB.cpp,其中包含用于調(diào)用Add函數(shù)的程序入口函數(shù)main。將剛才創(chuàng)建的Static.lib及其聲明頭文件Static.h一同復(fù)制到UseLIB項(xiàng)目目錄下。并在源文件UseLIB.cpp中使用預(yù)編譯命令鏈接Static.lib(也可以在IDE的項(xiàng)目屬性中設(shè)置鏈接器選項(xiàng),或者只復(fù)制Static.h文件并設(shè)置UseLIB項(xiàng)目的“項(xiàng)目依賴項(xiàng)”為Static項(xiàng)目)。
2021/6/27222.2靜態(tài)鏈接庫(kù)的使用源文件UseLIB.cpp中的代碼如下:#pragma
comment(lib,
“Static.lib”)
//
鏈接靜態(tài)庫(kù)Static.lib#include
<iostream.h>
#include
“Static.h”
//
包含Static.lib的聲明頭文件,聲明導(dǎo)出函數(shù)Add
int
main()
{
int
a
=
1,
b
=
2;
cout<<a<<"+"<<b<<"="<<Add(a,b);//
調(diào)用Static.lib中的Add函數(shù)
return
0;
}2021/6/27232.2靜態(tài)鏈接庫(kù)的使用接下來(lái)點(diǎn)擊菜單命令,“工具”-“生成UseLIB”。如果順利的話,就會(huì)在Library解決方案的Debug目錄中生成了名為UseLIB.exe的可執(zhí)行執(zhí)文件,運(yùn)行UseLIB.exe,將在控制臺(tái)中輸出結(jié)果:1+2=32021/6/27242.3注意由于項(xiàng)目中創(chuàng)建的源文件為.CPP文件,即C++源文件,因此Visual
C++按C++規(guī)范,并采用__cdecl調(diào)用約定對(duì)其進(jìn)行編譯。這樣得到的導(dǎo)出函數(shù)就不能被C語(yǔ)言程序所調(diào)用。解決該問(wèn)題的辦法是在函數(shù)體名稱前添加extern
“C”修飾,告訴編譯器,該函數(shù)按照C語(yǔ)言規(guī)范,并采用__cdecl調(diào)用約定進(jìn)行編譯。因此源文件Add.cpp中的代碼可修改如下:extern
“C”
int
add(int
a,
int
b)最后重新編譯該靜態(tài)鏈接庫(kù)項(xiàng)目,導(dǎo)出函數(shù)Add就能夠被C語(yǔ)言程序所調(diào)用了。2021/6/27253、動(dòng)態(tài)鏈接庫(kù)的創(chuàng)建2021/6/27263.1動(dòng)態(tài)鏈接庫(kù)的創(chuàng)建在此同樣通過(guò)一個(gè)實(shí)例來(lái)介紹動(dòng)態(tài)鏈接庫(kù)的創(chuàng)建與使用。在實(shí)例中,依然使用Add函數(shù)進(jìn)行講解,這樣一方面可以沿用上面靜態(tài)鏈接的有關(guān)內(nèi)容,另一方面也可以了解動(dòng)態(tài)鏈接庫(kù)與靜態(tài)鏈接庫(kù)在創(chuàng)建和使用上的異同。2021/6/27273.1.1創(chuàng)建一個(gè)Win32控制臺(tái)應(yīng)用程序2021/6/27283.1.2選擇靜態(tài)庫(kù)應(yīng)用程序類型2021/6/27293.1.3新建一個(gè).h文件編寫(xiě)一個(gè)聲明頭文件Dynamic.h,以便在以后鏈接時(shí)告知編譯器該鏈接庫(kù)中的具體的導(dǎo)入內(nèi)容(一般包括代碼和資源)。Dynamic.h:ifndef
__DYNAMIC_H__
//
防止該頭文件重復(fù)引用
#define
__DYNAMIC_H__
extern"C"__declspec(dllexport)
int
Add(int
a,
int
b);
//
聲明導(dǎo)出函數(shù)
#endif2021/6/27303.1.4新建一個(gè).cpp文件用于定義導(dǎo)出函數(shù)的源文件Dynamic.cpp,編碼實(shí)現(xiàn)兩個(gè)整數(shù)相加的Add函數(shù)。extern
“C”
__declspec(dllexport)
int
Add(int
a,
int
b)
//
聲明為DLL導(dǎo)出函數(shù)
{
return
a
+
b;
}2021/6/27313.1.4生成
點(diǎn)工具欄上的生成按鈕,則可以在debug下生成:2021/6/27322.2動(dòng)態(tài)鏈接庫(kù)的使用
1、載入時(shí)動(dòng)態(tài)鏈接
2、運(yùn)行時(shí)動(dòng)態(tài)鏈接2021/6/27332.2.1載入時(shí)動(dòng)態(tài)鏈接將導(dǎo)入庫(kù)Dynamic.lib及其聲明頭文件Dynamic.h一同復(fù)制到UseDLL項(xiàng)目目錄下,并把Dynamic.dll復(fù)制到項(xiàng)目的Debug目錄中。并在源文件UseDLL.cpp中使用預(yù)編譯命令鏈接Dynamic.lib(也可以在IDE的項(xiàng)目屬性中設(shè)置鏈接器選項(xiàng))。2021/6/2734
源文件UseDLL.cpp中的代碼如下:#pragma
comment(lib,
“Dynamic.lib”)
//
鏈接導(dǎo)入庫(kù)Dynamic.lib
#include
<iostream.h>
#include
“Dynamic.h”
//
聲明頭文件,提供導(dǎo)出函數(shù)Add的聲明
int
main()
{
int
a
=
1,
b
=
2;
cout<<a<<"+"<<b<<"="<<Add(a,b);
//
調(diào)用Dynamic.DLL中的Add函數(shù)
return0;}2021/6/27352.2.1運(yùn)行時(shí)動(dòng)態(tài)鏈接
運(yùn)行時(shí)動(dòng)態(tài)鏈接的代碼相對(duì)麻煩些,需要使用到Windows的三個(gè)API函數(shù),還要進(jìn)行一些判斷以防止不必要的麻煩。我們?cè)赨seDLL項(xiàng)目的基礎(chǔ)上做些修改來(lái)實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)鏈接。這里只需要把Dynamic.dll復(fù)制到UseDLL項(xiàng)目的Debug目錄中,因?yàn)椴挥迷诰幾g的時(shí)候鏈接導(dǎo)入庫(kù),只要在運(yùn)行根據(jù)需要鏈接Dynamic.dll。2021/6/27362.2.1運(yùn)行時(shí)動(dòng)態(tài)鏈接下面先給出修改后的源文件Dynamic.cpp的代碼:#include
<windows.h>
//
用于聲明window
API函數(shù)及宏等#include<iostream.h>typedef
int
(*
FuncAdd)(int
a,
int
b);
//
定義將要調(diào)用的導(dǎo)出函數(shù)Add的指針類型int
main()
{
FuncAdd
Add;
//
定義Add函數(shù)指針
int
a
=
1,
b
=
2;
HMODULE
hDLL
=
LoadLibrary(TEXT("MyDLL.dll"));
//
載入DLL,并獲取其句柄2021/6/2737
if
(hDLL)
//
MyDLL.dll載入成功
{
Add
=
(FuncAdd)GetProcAddress(hDLL,
"Add");
//
獲取導(dǎo)出函數(shù)Add指針
if
(Add)
//
正確獲取Add函數(shù)指針
{
cout<<a<<"+"<<b<<"="<<Add(a,b);
//
調(diào)用導(dǎo)出函數(shù)Add
}
else
//
沒(méi)有找到Add函數(shù)
{
cout<<"Add
Not
Found!\n";
}
}
else
//
MyDLL.dll載入失敗
cout<<"LoadLibrary
Failed!\n";
FreeLibrary((TEXT("MyDLL.dll"));
//
釋放DLL
return
0;
}2021/6/27382.2.1運(yùn)行時(shí)動(dòng)態(tài)鏈接
由于沒(méi)有鏈接導(dǎo)入庫(kù),不能使用地址符號(hào)定位導(dǎo)出函數(shù)的入口地址,只能通過(guò)GetProcAdress來(lái)獲取其在地址空間中的指針,再通過(guò)指針調(diào)用。但程序在運(yùn)行之前,GetProcAdress無(wú)法判斷指針的有效性。因此
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 合作合同范例.合作
- 銷(xiāo)售抵押合同范例
- 農(nóng)用設(shè)備采購(gòu)合同范例
- 銀行結(jié)清合同范例
- 2024初三英語(yǔ)教學(xué)計(jì)劃范文(30篇)
- 2025年江蘇貨運(yùn)從業(yè)資格證考試題及答案解析
- 2025年資陽(yáng)貨運(yùn)上崗證考試題庫(kù)
- 2025年莆田貨運(yùn)從業(yè)資格證網(wǎng)上考試答案
- 2024財(cái)務(wù)部門(mén)年度總結(jié)范文(34篇)
- 化學(xué)教師勞動(dòng)合同范本
- 財(cái)政投資評(píng)審咨詢服務(wù)預(yù)算和結(jié)算評(píng)審項(xiàng)目 投標(biāo)方案(技術(shù)方案)
- 江蘇省徐州市2022-2023學(xué)年三年級(jí)下學(xué)期語(yǔ)文期末考試試卷(含答案)2
- JGJ46-2005 施工現(xiàn)場(chǎng)臨時(shí)用電安全技術(shù)規(guī)范
- 果樹(shù)栽培學(xué)各論智慧樹(shù)知到期末考試答案章節(jié)答案2024年華南農(nóng)業(yè)大學(xué)、仲愷農(nóng)業(yè)工程學(xué)院
- PICC堵管原因與再通方法
- JB∕T 2900-2019 汽輪機(jī)涂裝技術(shù)條件
- GB/T 10395.28-2024農(nóng)業(yè)機(jī)械安全第28部分:移動(dòng)式谷物螺旋輸送機(jī)
- 勞務(wù)派遣技術(shù)服務(wù)方案
- 部編版小學(xué)三年級(jí)語(yǔ)文下冊(cè)《陶罐和鐵罐》課件
- ISO TR 15608-2017-中英文版完整
- 2024年度-全新新課標(biāo)培訓(xùn)
評(píng)論
0/150
提交評(píng)論