




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、 測繪學(xué)院:李新維 郵箱: 目目 錄錄 概念定義概念定義12 靜態(tài)鏈接庫的創(chuàng)建靜態(tài)鏈接庫的創(chuàng)建3動態(tài)鏈接庫的創(chuàng)建動態(tài)鏈接庫的創(chuàng)建4 應(yīng)用實例應(yīng)用實例1 1、概念定義、概念定義1.1 1.1 分別編譯與鏈接分別編譯與鏈接 大多數(shù)高級語言都支持分別編譯(compling),程序員可以顯式地把程序劃分為獨立的模塊或文件,然后由編譯器(compiler)對每個獨立部分分別進行編譯。在編譯之后,由鏈接器(Linker)把這些獨立編譯單元鏈接(Linking)到一起。 鏈接方式有兩種:靜態(tài)鏈接、動態(tài)鏈接。1.2 1.2 鏈接方式鏈接方式 靜態(tài)鏈接方式靜態(tài)鏈接方式:在程序開發(fā)中,將各種目標模塊(.OBJ)文
2、件、運行時庫(.LIB)文件,以及已編譯的資源(.RES)文件鏈接在一起,以便創(chuàng)建Windows的.EXE文件。 動態(tài)鏈接方式動態(tài)鏈接方式:在程序運行時,Windows把一個模塊中的函數(shù)調(diào)用鏈接到庫模塊中的實際函數(shù)上的過程。1.2 1.2 鏈接方式鏈接方式 靜態(tài)鏈接庫(簡稱LIB)與動態(tài)鏈接庫(簡稱DLL)都是共享代碼的方式。如果使用靜態(tài)鏈接庫(也稱靜態(tài)庫),則無論你愿不愿意,.LIB文件中的指令都會被直接包含到最終生成的.EXE文件中。但是若使用.DLL文件,該.DLL文件中的代碼不必被包含在最終的.EXE文件中,.EXE文件執(zhí)行時可以“動態(tài)”地載入和卸載這個與.EXE文件獨立的.DLL文件
3、。1.3 1.3 動態(tài)鏈接方式動態(tài)鏈接方式鏈接一個DLL有兩種方式: 1、載入時動態(tài)鏈接(Load-Time Dynamic Linking) 2、運行時動態(tài)鏈接(Run-Time Dynamic Linking) 1.3.1 1.3.1 載入時動態(tài)鏈接載入時動態(tài)鏈接 使用載入時動態(tài)鏈接,調(diào)用模塊可以像調(diào)用本模塊中的函數(shù)一樣直接使用導(dǎo)出函數(shù)名調(diào)用DLL中的函數(shù)。這需要在鏈接時將函數(shù)所在DLL的導(dǎo)入庫鏈接到可執(zhí)行文件中,導(dǎo)入庫向系統(tǒng)提供了載入DLL時所需的信息及用于定位DLL函數(shù)的地址符號。(相當(dāng)于注冊,當(dāng)作API函數(shù)來使用,其實API函數(shù)就存放在系統(tǒng)DLL當(dāng)中)。 1.3.2 1.3.2 運行
4、時動態(tài)鏈接運行時動態(tài)鏈接 使用運行時動態(tài)鏈接,運行時可以通過LoadLibrary或LoadLibraryEx函數(shù)載入DLL。DLL載入后,模塊可以通過調(diào)用GetProcAddress獲取DLL函數(shù)的入口地址,然后就可以通過返回的函數(shù)指針調(diào)用DLL中的函數(shù)了。如此即可避免導(dǎo)入庫文件了。 1.4 1.4 二者優(yōu)點及不足二者優(yōu)點及不足靜態(tài)鏈接庫的優(yōu)點:(1) 代碼裝載速度快,執(zhí)行速度略比動態(tài)鏈接庫快; (2) 只需保證在開發(fā)者的計算機中有正確的.LIB文件,在以二進制形式發(fā)布程序時不需考慮在用戶的計算機上.LIB文件是否存在及版本問題,可避免DLL地獄等問題。 1.4 1.4 二者優(yōu)點及不足二者優(yōu)
5、點及不足 動態(tài)鏈接庫的優(yōu)點 (1) 更加節(jié)省內(nèi)存并減少頁面交換; (2) DLL文件與EXE文件獨立,只要輸出接口不變(即名稱、參數(shù)、返回值類型和調(diào)用約定不變),更換DLL文件不會對EXE文件造成任何影響,因而極大地提高了可維護性和可擴展性; (3) 不同編程語言編寫的程序只要按照函數(shù)調(diào)用約定就可以調(diào)用同一個DLL函數(shù)。 1.4 1.4 二者優(yōu)點及不足二者優(yōu)點及不足不足之處 (1) 使用靜態(tài)鏈接生成的可執(zhí)行文件體積較大,包含相同的公共代碼,造成浪費; (2) 使用動態(tài)鏈接庫的應(yīng)用程序不是自完備的,它依賴的DLL模塊也要存在,如果使用載入時動態(tài)鏈接,程序啟動時發(fā)現(xiàn)DLL不存在,系統(tǒng)將終止程序并給
6、出錯誤信息。而使用運行時動態(tài)鏈接,系統(tǒng)不會終止,但由于DLL中的導(dǎo)出函數(shù)不可用,程序會加載失??; (3) 使用動態(tài)鏈接庫可能造成DLL地獄。 1.4.1 1.4.1 DLL DLL 地獄地獄 DLL 地獄(DLL Hell)是指因為系統(tǒng)文件被覆蓋而讓整個系統(tǒng)像是掉進了地獄。 簡單地講,DLL地獄是指當(dāng)多個應(yīng)用程序試圖共享一個公用組件時,如某個DLL或某個組件對象模型(COM)類,所引發(fā)的一系列問題。1.4.1 1.4.1 DLL DLL 地獄地獄 最典型的情況是,某個應(yīng)用程序?qū)⒁惭b一個新版本的共享組件,而該組件與機器上的現(xiàn)有版本不向后兼容。雖然剛安裝的應(yīng)用程序運行正常,但原來依賴前一版本共享
7、組件的應(yīng)用程序也許已無法再工作。在某些情況下,問題的起因更加難以預(yù)料。比如,當(dāng)用戶瀏覽某些web站點時會同時下載某個Microsoft ActiveX控件。如果下載該控件,它將替換機器上原有的任何版本的控件。如果機器上的某個應(yīng)用程序恰好使用該控件,則很可能也會停止工作。 在許多情況下,用戶需要很長時間才會發(fā)現(xiàn)應(yīng)用程序已停止工作。結(jié)果往往很難記起是何時的機器變化影響到了該應(yīng)用程序。2 2、靜態(tài)鏈接庫的創(chuàng)建靜態(tài)鏈接庫的創(chuàng)建2.1 2.1 靜態(tài)鏈接庫的創(chuàng)建靜態(tài)鏈接庫的創(chuàng)建 在此通過一個實例來介紹靜態(tài)庫的創(chuàng)建與使用。在該實例中,我們實現(xiàn)將一個兩整數(shù)相加求和的函數(shù)封裝到靜態(tài)庫中供其他程序調(diào)用。2.1.1
8、 2.1.1 創(chuàng)建一個創(chuàng)建一個Win32Win32控制臺應(yīng)用程序控制臺應(yīng)用程序2.1.2 2.1.2 選擇靜態(tài)庫應(yīng)用程序類型選擇靜態(tài)庫應(yīng)用程序類型2.1.3 2.1.3 新建一個新建一個.h .h文件文件 需要給該靜態(tài)鏈接庫編寫一個聲明頭文件Static.h,以便在鏈接時告知編譯該鏈接庫中的導(dǎo)出函數(shù)聲明。Static.h文件中的內(nèi)容: #ifndef _STATIC_H #define _STATIC_H / 防止該頭文件重復(fù)引用 extern int Add(int a,int b); / 聲明導(dǎo)出函數(shù) #endif2.1.4 2.1.4 新建一個新建一個.cpp.cpp文件文件 添加一個用
9、于定義導(dǎo)出函數(shù)的源文件Static.cpp,編碼實現(xiàn)兩個整數(shù)相加的Add函數(shù)。源文件代碼如下: #includestatic.h int Add(int a,int b) return a+b; 2.1.5 2.1.5 生成生成 點擊菜單命令,“工具”-“生成Static”。如果一切順利的話,就會在解決方案的“Debug”目錄中生成了名為“Static.lib”的靜態(tài)鏈接庫。2.2 2.2 靜態(tài)鏈接庫的使用靜態(tài)鏈接庫的使用 新建一個Win32控制臺應(yīng)用程序空項目UseLIB。程序主文件名為UseLIB.cpp,其中包含用于調(diào)用Add函數(shù)的程序入口函數(shù)main。將剛才創(chuàng)建的Static.lib及
10、其聲明頭文件Static.h一同復(fù)制到UseLIB項目目錄下。并在源文件UseLIB.cpp中使用預(yù)編譯命令鏈接Static.lib(也可以在IDE的項目屬性中設(shè)置鏈接器選項,或者只復(fù)制Static.h文件并設(shè)置UseLIB項目的“項目依賴項”為Static項目)。 2.2 2.2 靜態(tài)鏈接庫的使用靜態(tài)鏈接庫的使用源文件UseLIB.cpp中的代碼如下:#pragma comment(lib, “Static.lib”) / 鏈接靜態(tài)庫Static.lib#include #include “Static.h” / 包含Static.lib的聲明頭文件,聲明導(dǎo)出函數(shù)Add int main()
11、 int a = 1, b = 2; couta+b=Add(a,b); / 調(diào)用Static.lib中的Add函數(shù) return 0; 2.2 2.2 靜態(tài)鏈接庫的使用靜態(tài)鏈接庫的使用 接下來點擊菜單命令,“工具”-“生成UseLIB”。如果順利的話,就會在Library解決方案的Debug目錄中生成了名為UseLIB.exe的可執(zhí)行執(zhí)文件,運行UseLIB.exe,將在控制臺中輸出結(jié)果:1+2=32.3 2.3 注意注意 由于項目中創(chuàng)建的源文件為.CPP文件,即C+源文件,因此Visual C+按C+規(guī)范,并采用_cdecl調(diào)用約定對其進行編譯。這樣得到的導(dǎo)出函數(shù)就不能被C語言程序所調(diào)用。
12、解決該問題的辦法是在函數(shù)體名稱前添加extern “C”修飾,告訴編譯器,該函數(shù)按照C語言規(guī)范,并采用_cdecl調(diào)用約定進行編譯。因此源文件Add.cpp中的代碼可修改如下:extern “C” int add(int a, int b)最后重新編譯該靜態(tài)鏈接庫項目,導(dǎo)出函數(shù)Add就能夠被C語言程序所調(diào)用了。3 3、動、動態(tài)鏈接庫的創(chuàng)建態(tài)鏈接庫的創(chuàng)建3.1 3.1 動態(tài)鏈接庫的創(chuàng)建動態(tài)鏈接庫的創(chuàng)建 在此同樣通過一個實例來介紹動態(tài)鏈接庫的創(chuàng)建與使用。在實例中,依然使用Add函數(shù)進行講解,這樣一方面可以沿用上面靜態(tài)鏈接的有關(guān)內(nèi)容,另一方面也可以了解動態(tài)鏈接庫與靜態(tài)鏈接庫在創(chuàng)建和使用上的異同。3.
13、1.1 3.1.1 創(chuàng)建一個創(chuàng)建一個Win32Win32控制臺應(yīng)用程序控制臺應(yīng)用程序3.1.2 3.1.2 選擇靜態(tài)庫應(yīng)用程序類型選擇靜態(tài)庫應(yīng)用程序類型3.1.3 3.1.3 新建一個新建一個.h .h文件文件 編寫一個聲明頭文件Dynamic.h,以便在以后鏈接時告知編譯器該鏈接庫中的具體的導(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ù) #endif3.1.4
14、3.1.4 新建一個新建一個.cpp.cpp文件文件 用于定義導(dǎo)出函數(shù)的源文件Dynamic.cpp,編碼實現(xiàn)兩個整數(shù)相加的Add函數(shù)。extern “C” _declspec(dllexport) int Add(int a, int b) / 聲明為DLL導(dǎo)出函數(shù) return a + b; 3.1.4 3.1.4 生成生成 點工具欄上的生成按鈕,則可以在debug下生成:2.2 2.2 動態(tài)鏈接庫的使用動態(tài)鏈接庫的使用 1、載入時動態(tài)鏈接、載入時動態(tài)鏈接 2、運行時動態(tài)鏈接、運行時動態(tài)鏈接2.2.1 2.2.1 載入時動態(tài)鏈接載入時動態(tài)鏈接 將導(dǎo)入庫Dynamic.lib及其聲明頭文件D
15、ynamic.h一同復(fù)制到UseDLL項目目錄下,并把Dynamic.dll復(fù)制到項目的Debug目錄中。并在源文件UseDLL.cpp中使用預(yù)編譯命令鏈接Dynamic.lib(也可以在IDE的項目屬性中設(shè)置鏈接器選項)。 源文件源文件UseDLL.cpp中的代碼如下:中的代碼如下:#pragma comment(lib, “Dynamic.lib”) / 鏈接導(dǎo)入庫Dynamic.lib #include #include “Dynamic.h” / 聲明頭文件,提供導(dǎo)出函數(shù)Add的聲明 int main() int a = 1, b = 2; couta+b=Add(a,b); / 調(diào)用
16、Dynamic.DLL中的Add函數(shù) return 0;2.2.1 2.2.1 運行時動態(tài)鏈接運行時動態(tài)鏈接 運行時動態(tài)鏈接的代碼相對麻煩些,需要使用到Windows的三個API函數(shù),還要進行一些判斷以防止不必要的麻煩。我們在UseDLL項目的基礎(chǔ)上做些修改來實現(xiàn)運行時動態(tài)鏈接。這里只需要把Dynamic.dll復(fù)制到UseDLL項目的Debug目錄中,因為不用在編譯的時候鏈接導(dǎo)入庫,只要在運行根據(jù)需要鏈接Dynamic.dll。2.2.1 2.2.1 運行時動態(tài)鏈接運行時動態(tài)鏈接 下面先給出修改后的源文件Dynamic.cpp的代碼:#include / 用于聲明window API函數(shù)及宏
17、等#includetypedef 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,并獲取其句柄 if (hDLL) / MyDLL.dll載入成功 Add = (FuncAdd)GetProcAddress(hDLL, Add); / 獲取導(dǎo)出函數(shù)Add指針 if (Add) / 正確獲取Add函數(shù)指針 couta+b=Add(
18、a,b); / 調(diào)用導(dǎo)出函數(shù)Add else / 沒有找到Add函數(shù) coutAdd Not Found!n; else / MyDLL.dll載入失敗 coutLoadLibrary Failed!n; FreeLibrary(TEXT(MyDLL.dll); / 釋放DLL return 0; 2.2.1 2.2.1 運行時動態(tài)鏈接運行時動態(tài)鏈接 由于沒有鏈接導(dǎo)入庫,不能使用地址符號定位導(dǎo)出函數(shù)的入口地址,只能通過GetProcAdress來獲取其在地址空間中的指針,再通過指針調(diào)用。但程序在運行之前,GetProcAdress無法判斷指針的有效性。因此,為了防止Dynamic項目中不存在Add函數(shù)而
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 偏關(guān)輔警考試題庫2025含答案
- 2025年四川成都人民網(wǎng)分公司招聘考試筆試試題(含答案)
- 老年護理跌倒課件
- 老年護理學(xué)臨終護理課件
- 倉儲租賃及倉儲信息化服務(wù)合同
- 車輛股權(quán)轉(zhuǎn)讓與配套配件銷售及售后服務(wù)合同
- 生態(tài)草場使用權(quán)轉(zhuǎn)讓與維護合同
- 財務(wù)顧問綜合管理與專業(yè)培訓(xùn)合同
- 木材車隊運輸管理協(xié)議
- 金融機構(gòu)財務(wù)人員擔(dān)保及信用擔(dān)保合同
- 免疫檢查點抑制劑相關(guān)肺炎診治和管理專家共識(2025)要點解讀
- (統(tǒng)編版2025)歷史七年級下冊新教材變化及教學(xué)建議
- 板式家具生產(chǎn)工藝流程
- 文化安全課件
- 植保知識無人機課件圖片
- 蠶桑養(yǎng)殖知識培訓(xùn)課件
- 材料欠款擔(dān)保協(xié)議書
- T-CCASC 0038-2024 廢鹽為原料離子膜法燒堿應(yīng)用核查技術(shù)規(guī)范
- 輸血錯誤應(yīng)急預(yù)案及處理流程
- 游戲代練創(chuàng)新創(chuàng)業(yè)方案
- 拆除臨時用電施工方案
評論
0/150
提交評論