一、COM
COM(Component Object Model)是最近WIndows世界中最流行的TLA(three-letter acronym)。一些新技術(shù)的出現(xiàn)都是基于COM的。并且這些技術(shù)文檔中拋出了很多術(shù)語(yǔ),比如 「COM對(duì)象」 、 「接口」 、 「服務(wù)器」 等等,但都假設(shè)您已熟悉COM的基本工作原理和使用方法。
COM到底是什么
簡(jiǎn)單地說(shuō),COM是一種跨不同應(yīng)用程序和語(yǔ)言共享二進(jìn)制代碼的方法。這與c++方法不同,后者促進(jìn)了源代碼的重用。ATL就是一個(gè)很好的例子。雖然源代碼級(jí)重用可以很好地工作,但它只適用于c++。它還引入了名稱(chēng)沖突的可能性,更不用說(shuō)在項(xiàng)目中擁有多個(gè)代碼副本而導(dǎo)致的工程膨脹和臃腫。
Windows允許使用dll在二進(jìn)制級(jí)別上共享代碼。畢竟,這就是Windows應(yīng)用程序的功能——重用kernel32.dll, user32.dll,等等。但是由于dll是寫(xiě)在C接口上的,所以它們只能由C或理解C調(diào)用約定的語(yǔ)言使用。這就把共享的重?fù)?dān)放在了編程語(yǔ)言實(shí)現(xiàn)者身上,而不是DLL本身。
MFC通過(guò)MFC擴(kuò)展dll引入了另一種二進(jìn)制共享機(jī)制。但是這些限制更加嚴(yán)格——你只能從MFC應(yīng)用程序中使用它們。
COM通過(guò)定義二進(jìn)制標(biāo)準(zhǔn)解決了所有這些問(wèn)題,這意味著COM指定二進(jìn)制模塊(dll和exe)必須被編譯以匹配特定的結(jié)構(gòu)。該標(biāo)準(zhǔn)還精確地指定了在內(nèi)存中必須如何組織COM對(duì)象。二進(jìn)制文件還必須不依賴(lài)于任何編程語(yǔ)言的任何特性(比如c++中的名稱(chēng)裝飾)。一旦完成了這些,就可以很容易地從任何編程語(yǔ)言訪問(wèn)模塊。二進(jìn)制標(biāo)準(zhǔn)將兼容性的重?fù)?dān)壓在了生成二進(jìn)制文件的編譯器上,這使得以后需要使用這些二進(jìn)制文件的人更加容易。
內(nèi)存中COM對(duì)象的結(jié)構(gòu)恰好使用與c++虛函數(shù)相同的結(jié)構(gòu),這就是為什么許多COM代碼使用c++的原因。但是請(qǐng)記住,編寫(xiě)模塊所用的語(yǔ)言是不相關(guān)的,因?yàn)樯傻亩M(jìn)制文件可以被所有語(yǔ)言使用。
順便說(shuō)一句,COM不是特定于win32的。理論上,它可以移植到Unix或任何其他操作系統(tǒng)。然而,我似乎從來(lái)沒(méi)有提到過(guò)COM以外的Windows世界。
使用COM對(duì)象
每種語(yǔ)言都有自己處理對(duì)象的方式。例如,在c++中,您可以在棧上創(chuàng)建它們,或者使用new動(dòng)態(tài)地分配它們。因?yàn)镃OM必須是語(yǔ)言無(wú)關(guān)的,所以COM庫(kù)提供了自己的對(duì)象管理例程。COM和c++對(duì)象管理的比較如下:
「創(chuàng)建一個(gè)對(duì)象」
C++中,使用?「operator new」?或者在棧中創(chuàng)建一個(gè)對(duì)象COM中,調(diào)用COM庫(kù)的API創(chuàng)建「刪除一個(gè)對(duì)象」
C++中,使用?「operator delete」?或者棧中的對(duì)象作用域消失時(shí),釋放這個(gè)對(duì)象COM中,所有對(duì)象都保留自己的引用計(jì)數(shù)。調(diào)用者必須在調(diào)用者使用對(duì)象完成時(shí)告訴對(duì)象。當(dāng)引用計(jì)數(shù)達(dá)到0時(shí),COM對(duì)象從內(nèi)存中釋放自己。由此可見(jiàn),對(duì)象的創(chuàng)建和銷(xiāo)毀這兩個(gè)階段缺一不可。當(dāng)你創(chuàng)建一個(gè)COM對(duì)象時(shí),你告訴COM庫(kù)你需要什么接口。如果對(duì)象被成功創(chuàng)建,COM庫(kù)返回一個(gè)指向所請(qǐng)求接口的指針。然后,您可以通過(guò)該指針調(diào)用方法,就像它是一個(gè)普通c++對(duì)象的指針一樣。
延伸閱讀:
二、dwFlags是什么
dwFlags確定Windows如何處理“復(fù)合”Unicode字符,即字母后跟變音符號(hào)。復(fù)合字符的一個(gè)例子是e。如果此字符位于代碼頁(yè)中指定的代碼頁(yè)中,則不會(huì)發(fā)生任何特殊情況。但是,如果它不在代碼頁(yè)中,Windows必須將其轉(zhuǎn)換為其他內(nèi)容。 傳遞WC_COMPOSITECHECK使API檢查非映射的復(fù)合字符。傳遞WC_SEPCHARS使Windows將字符分成兩個(gè)部分,字母后跟變音符號(hào),例如e ‘。傳遞WC_DISCARDNS會(huì)使Windows放棄變音符號(hào)。傳遞WC_DEFAULTCHAR將使Windows用lpDefaultChar參數(shù)中指定的“默認(rèn)”字符替換復(fù)合字符。默認(rèn)行為是WC_SEPCHARS。