句柄和實(shí)例怎樣區(qū)別?
熱心網(wǎng)友
從Visual C++的頭文件來看,HANDLE被typedef為void的指針,那是指向未確定數(shù)據(jù)結(jié)構(gòu)的指針:typedef void* HANDLE; 但是這并不說明任何問題,因?yàn)榫浔h(yuǎn)遠(yuǎn)不只是指向任意數(shù)據(jù)類型的指針。它是指向數(shù)據(jù)對(duì)象指針的指針。句柄的使用來源于早期的Windows,當(dāng)時(shí)它只能在有限內(nèi)存的機(jī)器中允許(因?yàn)楫?dāng)時(shí)內(nèi)存昂貴也存儲(chǔ)小)。為了留出足夠的空間內(nèi)存以運(yùn)行其他程序,Windows經(jīng)常將對(duì)象在內(nèi)存中移動(dòng)。但是如果進(jìn)程已經(jīng)有了指向該對(duì)象的指針,移動(dòng)該對(duì)象就將使得指針無效。 為了處理這一問題,Microsoft使用系統(tǒng)指針以跟蹤對(duì)象。程序不是直接使用指針,而是使用句柄,讓它引用包含真實(shí)對(duì)象的地址。通過這一方法,Windows可以安全按照需要移動(dòng)對(duì)象,然后更新參考中的指針,從而允許進(jìn)程安全地訪問對(duì)象。 當(dāng)進(jìn)程需要使用句柄訪問對(duì)象時(shí),它調(diào)用GlobalLocl()以鎖定內(nèi)存的對(duì)象。這時(shí)Windows將返回對(duì)象的實(shí)際地址,從而進(jìn)程可以安全讀寫該對(duì)象。只要對(duì)象被進(jìn)程鎖定,Windows就不會(huì)去移動(dòng)它。句柄包含的不只是對(duì)象的地址;比如,它還包含鎖計(jì)數(shù)器,標(biāo)識(shí)著多少進(jìn)程已經(jīng)請(qǐng)求過對(duì)象的地址。只要這個(gè)鎖計(jì)數(shù)器大于0,Windows就不會(huì)移動(dòng)該對(duì)象。 這個(gè)思想擴(kuò)展到大部分對(duì)象上,包括文件,也由其句柄標(biāo)識(shí)。 這時(shí),句柄就是指向?qū)ο蟮闹羔槪搶?duì)象包含指向另一個(gè)對(duì)象的指針。這對(duì)于現(xiàn)在的機(jī)器有些奇怪。當(dāng)Windows從單個(gè)分時(shí)共享程序向多任務(wù)操作系統(tǒng)轉(zhuǎn)變時(shí),有如此之多的遺留代碼需要在新的操作系統(tǒng)上運(yùn)行,于是句柄在這一轉(zhuǎn)變中保留下來了。。