自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么動(dòng)態(tài)鏈接庫(kù)以"錯(cuò)誤"的方式被卸載?

數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
在標(biāo)記為 “oops” 的行中,不能保證 B.DLL 仍在內(nèi)存中,因?yàn)?B.DLL 不會(huì)出現(xiàn)在 A.DLL 的依賴項(xiàng)列表中,即使存在由對(duì) LoadLibrary 的調(diào)用導(dǎo)致的運(yùn)行時(shí)生成的動(dòng)態(tài)依賴項(xiàng)。

?當(dāng)程序啟動(dòng)或加載 DLL 時(shí),加載器將生成該程序/DLL 引用的所有 DLL、該 DLL 的依賴項(xiàng)等的依賴項(xiàng)樹。然后,它確定初始化這些 DLL 的正確順序,以便在初始化它所依賴的所有 DLL 之前,不會(huì)初始化任何 DLL。(當(dāng)然,如果你有一個(gè)循環(huán)依賴關(guān)系,那么它就會(huì)崩潰。眾所周知,從 DLL 的DLL_PROCESS_ATTACH 通知中調(diào)用加載庫(kù)函數(shù)或 LoadLibraryEx 函數(shù)也會(huì)弄亂這些依賴項(xiàng)的計(jì)算過(guò)程。)

同樣,當(dāng)卸載 DLL 或程序終止時(shí),將進(jìn)行反初始化,以便在 DLL 的所有依賴項(xiàng)之后反初始化該 DLL。

但是,當(dāng)你手動(dòng)加載 DLL 時(shí),關(guān)鍵信息會(huì)丟失:即調(diào)用 LoadLibrary 的 DLL 取決于正在被加載的 DLL。因此,如果 A.DLL 手動(dòng)加載 B.DLL,則不能保證 A.DLL 將在 B.DLL 之前卸載。這意味著,例如,像下面這樣的代碼是不可靠的:

在標(biāo)記為 “oops” 的行中,不能保證 B.DLL 仍在內(nèi)存中,因?yàn)?B.DLL 不會(huì)出現(xiàn)在 A.DLL 的依賴項(xiàng)列表中,即使存在由對(duì) LoadLibrary 的調(diào)用導(dǎo)致的運(yùn)行時(shí)生成的動(dòng)態(tài)依賴項(xiàng)。

為什么加載器無(wú)法跟蹤此動(dòng)態(tài)依賴項(xiàng)?換句話說(shuō),當(dāng)A.DLL調(diào)用LoadLibrary(“B.DLL”) 時(shí),為什么加載器不能自動(dòng)說(shuō)“好吧,現(xiàn)在A.DLL依賴于B.DLL”?

首先,因?yàn)檎缥以谥暗奈恼轮兴赋龅?,你不能相信返回地址?/p>

其次,即使你可以相信返回地址,你仍然不能相信返回地址。我們看看下面的代碼:

在這種情況下,B.DLL 的加載不是直接從A.DLL發(fā)生的,而是通過(guò)中間(在本例中為中間函數(shù))發(fā)生的。即使你可以相信返回地址,依賴項(xiàng)也會(huì)分配給 MID.DLL 而不是A.DLL。

你可能會(huì)問,”什么樣的人會(huì)寫出像中函數(shù)這樣的函數(shù)呢?”。這種中間函數(shù)在幫助函數(shù)/包裝器函數(shù)很常見,或者為了提供額外的生存期管理功能(盡管它現(xiàn)在不再這樣做了,但是它曾經(jīng)這樣做過(guò))。

第三,有調(diào)用 GetModuleHandle 函數(shù)的情況。我們看看下面的代碼:

我們對(duì) GetModuleHandle 的調(diào)用,是否應(yīng)創(chuàng)建依賴項(xiàng)呢?

另請(qǐng)注意,DLL 之間存在的依賴關(guān)系不僅僅是對(duì) LoadLibrary 的調(diào)用。例如,如果將回調(diào)函數(shù)指針傳遞給另一個(gè) DLL,則就會(huì)創(chuàng)建一個(gè)反向依賴項(xiàng)。

最后要注意的是,這種隱式依賴關(guān)系,就像上面寫的那樣很難看到,一旦你把全局析構(gòu)函數(shù)扔進(jìn)去,情況就更糟了。例如下面的代碼:

DLL 依賴項(xiàng)現(xiàn)在隱藏在 SomethingHolder 類中,當(dāng) A.DLL 卸載時(shí),g_SomethingHolder的析構(gòu)函數(shù)將運(yùn)行并嘗試與 B.DLL 通信。隨之而來(lái)的,是程序的不可預(yù)知的行為。

總結(jié)

盡量不對(duì)系統(tǒng)運(yùn)行行為做出過(guò)多的假設(shè),嚴(yán)格按照 MSDN 所說(shuō)的,老老實(shí)實(shí)寫你的代碼,基本不會(huì)有大錯(cuò)誤。

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2024-06-06 08:53:13

動(dòng)態(tài)鏈接庫(kù)共享庫(kù)

2012-05-08 14:48:23

LinuxUnix動(dòng)態(tài)鏈接庫(kù)

2012-05-04 08:24:14

LinuxUnix

2011-06-21 18:02:14

Qt 動(dòng)態(tài) 鏈接庫(kù)

2009-07-07 20:57:20

LinuxUnix動(dòng)態(tài)鏈接庫(kù)

2022-06-09 09:54:45

編譯軟件開發(fā)

2009-08-28 16:19:30

C#實(shí)現(xiàn)修改動(dòng)態(tài)鏈接庫(kù)

2022-05-03 23:44:21

Python動(dòng)態(tài)鏈接庫(kù)Ctypes

2024-03-01 20:59:11

C#DLL開發(fā)

2023-11-29 08:31:20

PythonRust

2011-05-18 17:15:45

2009-08-05 16:29:18

C#調(diào)用C++動(dòng)態(tài)鏈接

2023-05-09 08:24:11

JNA鏈接庫(kù)代碼

2009-10-29 16:36:49

VB.NET .DLL

2022-08-09 07:57:25

Linux操作系統(tǒng)Windows

2011-08-02 14:15:05

XCode 靜態(tài) 鏈接庫(kù)

2022-07-12 13:23:59

靜態(tài)鏈接庫(kù)可執(zhí)行文件C 目標(biāo)文件

2021-09-01 05:11:13

C# 動(dòng)態(tài)鏈接庫(kù)

2012-01-06 10:25:50

JavaDLLC++

2011-09-06 16:30:32

iOS系統(tǒng)靜態(tài)鏈接庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)