COM組件
?
COM component(COM組件)是微軟公司為了計(jì)算機(jī)工業(yè)的軟件生產(chǎn)更加符合人類的行為方式開發(fā)的一種新的軟件開發(fā)技術(shù)。在COM構(gòu)架下,人們可以開發(fā)出各種各樣的功能專一的組件,然后將它們按照需要組合起來,構(gòu)成復(fù)雜的應(yīng)用系統(tǒng)。由此帶來的好處是多方面的:可以將系統(tǒng)中的組件用新的替換掉,以便隨時(shí)進(jìn)行系統(tǒng)的升級(jí)和定制;可以在多個(gè)應(yīng)用系統(tǒng)中重復(fù)利用同一個(gè)組件;可以方便的將應(yīng)用系統(tǒng)擴(kuò)展到網(wǎng)絡(luò)環(huán)境下;COM與語言,平臺(tái)無關(guān)的特性使所有的程序員均可充分發(fā)揮自己的才智與專長編寫組件模塊。
?
COM方法
COM是開發(fā)
軟件組件
的一種方法。組件實(shí)際上是一些小的二進(jìn)制可執(zhí)行程序,它們可以給應(yīng)用程序,操作系統(tǒng)以及其他組件提供服務(wù)。開發(fā)自定義的COM組件就如同開發(fā)動(dòng)態(tài)的,
面向?qū)ο?
的API。多個(gè)COM對(duì)象可以連接起來形成應(yīng)用程序或組件系統(tǒng)。并且組件可以在運(yùn)行時(shí)刻,在不被重新鏈接或編譯應(yīng)用程序的情況下被卸下或替換掉。Microsoft的許多技術(shù),如ActiveX, DirectX以及OLE等都是基于COM而建立起來的。并且Microsoft的開發(fā)人員也大量使用COM組件來定制他們的應(yīng)用程序及操作系統(tǒng)。
COM所含的概念并不止是在Microsoft Windows操作系統(tǒng)下才有效。COM并不是一個(gè)大的API,它實(shí)際上像
結(jié)構(gòu)化編程
及面向?qū)ο缶幊谭椒菢樱彩且环N編程方法。在任何一種操作系統(tǒng)中,開發(fā)人員均可以遵循“COM方法”。
一個(gè)應(yīng)用程序通常是由單個(gè)的
二進(jìn)制文件
組成的。當(dāng)
編譯器
生成應(yīng)用程序之后,在對(duì)下一個(gè)版本重新編譯并發(fā)行新生成的版本之前,應(yīng)用程序一般不會(huì)發(fā)生任何變化。操作系統(tǒng),硬件及客戶需求的改變都必須等到整個(gè)應(yīng)用程序被重新生成。
目前這種狀況已經(jīng)發(fā)生變化。開發(fā)人員開始將單個(gè)的應(yīng)用程序分隔成單獨(dú)多個(gè)獨(dú)立的部分,也即組件。這種做法的好處是可以隨著技術(shù)的不斷發(fā)展而用新的組件取代已有的組件。此時(shí)的應(yīng)用程序可以隨新組件不斷取代舊的組件而漸趨完善。而且利用已有的組件,用戶還可以快速的建立全新的應(yīng)用。
傳統(tǒng)的做法是將應(yīng)用程序分割成文件,模塊或類,然后將它們編譯并鏈接成一個(gè)單模應(yīng)用程序。它與組件建立應(yīng)用程序的過程(稱為組件構(gòu)架)有很大的不同。一個(gè)組件同一個(gè)微型應(yīng)用程序類似,即都是已經(jīng)編譯鏈接好并可以使用的
二進(jìn)制代碼
,應(yīng)用程序就是由多個(gè)這樣的組件打包而得到的。單模應(yīng)用程序只有一個(gè)
二進(jìn)制代碼
模塊。自定義組件可以在運(yùn)行時(shí)刻同其他的組件連接起來以構(gòu)成某個(gè)應(yīng)用程序。在需要對(duì)應(yīng)用程序進(jìn)行修改或改進(jìn)時(shí),只需要將構(gòu)成此應(yīng)用程序的組件中的某個(gè)用新的版本替換掉即可。
COM,即
組件對(duì)象模型
,是關(guān)于如何建立組件以及如何通過組件建立應(yīng)用程序的一個(gè)規(guī)范,說明了如何可動(dòng)態(tài)交替更新組件。
組件優(yōu)點(diǎn)
組件架構(gòu)的一個(gè)優(yōu)點(diǎn)就是應(yīng)用可以隨時(shí)間的流逝而發(fā)展進(jìn)化。除此之外,使用組件還有一些可以使對(duì)已有應(yīng)用的升級(jí)更加方便和靈活的優(yōu)點(diǎn),如應(yīng)用的定制,組件庫以及
分布式組件
等。
使用組件的種種優(yōu)點(diǎn)直接來源于可以將它們動(dòng)態(tài)的插入或卸出應(yīng)用。為了實(shí)現(xiàn)這種功能,所有的組件必須滿足兩個(gè)條件:第一,組件必須
動(dòng)態(tài)鏈接
;第二,它們必須隱藏(或
封裝
)其內(nèi)部實(shí)現(xiàn)細(xì)節(jié)。
動(dòng)態(tài)鏈接
對(duì)于組件而言是一個(gè)至關(guān)重要的要求,而消息隱藏則是動(dòng)態(tài)鏈接的一個(gè)必要條件。
COM組件由以Win 32
動(dòng)態(tài)連接庫
(DLL)或
可執(zhí)行文件
(EXE)形式發(fā)布的
可執(zhí)行代碼
所組成。遵循COM規(guī)范編寫出來的組件將能夠滿足對(duì)組件架構(gòu)的所有要求。COM組件可以給應(yīng)用程序、操作系統(tǒng)以及其他組件提供服務(wù);自定義的COM組件可以在運(yùn)行時(shí)刻同其他組件連接起來構(gòu)成某個(gè)應(yīng)用程序;COM組件可以動(dòng)態(tài)的插入或卸出應(yīng)用。
惡意網(wǎng)站
可以利用含有漏洞的com組件接口,
下載木馬
,并且執(zhí)行;
禁用com組件一般是指設(shè)置了Kill位,即IE瀏覽器不能使用這個(gè)組件,通俗講:通過設(shè)置Kill位,可以使InternetExplorer在使用默認(rèn)設(shè)置時(shí)永不調(diào)用被禁用的com組件,從而禁止該控件在Internet Explorer中運(yùn)行。禁用含有漏洞的com組件后,IE就不能調(diào)用含有漏洞的COM組件;黑客利用有漏洞的COM組,寫成的
網(wǎng)頁代碼
就不能在IE中被執(zhí)行,木馬等將不會(huì)被下載。
相關(guān)問題
禁用com組件可能導(dǎo)致的問題
在線播放功能的組件被禁用,會(huì)導(dǎo)致在線電影等在線視頻無法正常觀看;
在線殺毒
功能的組件被禁用,會(huì)導(dǎo)致在線殺毒不能使用;
在線游戲功能的組件被禁用,會(huì)導(dǎo)致在線游戲無法玩,
com組件禁用后的具體情況,需要根據(jù)具體的com組件功能作判斷。
手動(dòng)啟動(dòng)COM組件操作方法:
運(yùn)行——regedit——找到被禁用的com組件對(duì)應(yīng)的clsid|
注冊(cè)表鍵值
——?jiǎng)h除具體值,或者整個(gè)鍵。
COM是Component Object Model (
組件對(duì)象模型
)的縮寫。 用戶需要什么樣的軟件產(chǎn)品?這是一個(gè)多選題,但高效,健壯是肯定會(huì)被選中的。作為一名軟件開發(fā)人員如何做才能滿足用戶的需要呢?必須要保證升級(jí)應(yīng)用時(shí)不破壞與以前版本的向后兼容性。必須做到擴(kuò)展
系統(tǒng)服務(wù)
時(shí)不依賴特定的操作系統(tǒng)。
面向?qū)ο蟮某绦蛟O(shè)計(jì)
顯然是一次革命性的改變。采用
面向?qū)ο?
的設(shè)計(jì)方法我們可以很容易的把要解決的問題事物抽象成各種類,并將內(nèi)部動(dòng)作封裝隱藏起來,只提供一些接口。但這并沒有完全解決我們的問題。昨天我在《程序員》雜志上看到,現(xiàn)在是后OO時(shí)代,那OO以后是什么呢?應(yīng)該是
面向組件
吧。
手動(dòng)啟動(dòng)COM組件操作方法:
運(yùn)行——regedit——找到被禁用的com組件對(duì)應(yīng)的clsid|注冊(cè)表鍵值——?jiǎng)h除具體值,或者整個(gè)鍵。
剛剛讀完《COM技術(shù)內(nèi)幕》一書,整理了一個(gè)FAQ,供大家在學(xué)習(xí)此書時(shí)參考。
這是第一部分,包含前3章的內(nèi)容。
FAQ1:什么是COM組件?〖第一章〗
Answer:
COM組件是以WIN32
動(dòng)態(tài)鏈接庫
(DLL)或可執(zhí)行文件(EXE)形式發(fā)布的可執(zhí)行代碼組成。
COM組件是遵循COM規(guī)范編寫的
COM組件是一些小的二進(jìn)制可執(zhí)行文件
COM組件可以給應(yīng)用程序、操作系統(tǒng)以及其他組件提供服務(wù)
自定義的COM組件可以在運(yùn)行時(shí)刻同其他組件連接起來構(gòu)成某個(gè)應(yīng)用程序
COM組件可以動(dòng)態(tài)的插入或卸出應(yīng)用
COM組件必須是動(dòng)態(tài)鏈接的
COM組件必須隱藏(封裝)其內(nèi)部實(shí)現(xiàn)細(xì)節(jié)
COM組件必須將其實(shí)現(xiàn)的語言隱藏
COM組件必須以二進(jìn)制的形式發(fā)布
COM組件必須可以在不妨礙已有用戶的情況下被升級(jí)
COM組件可以透明的在網(wǎng)絡(luò)上被重新分配位置
COM組件按照一種標(biāo)準(zhǔn)的方式來宣布它們的存在
FAQ2:組件不是……?〖第一章〗
Answer:
COM組件不是一種計(jì)算機(jī)語言
COM組件不是DLL,只是利用DLL來給組件提供
動(dòng)態(tài)鏈接
的能力
COM組件不是一個(gè)API函數(shù)集。
COM組件不是類
FAQ3:什么是接口?〖第二章〗
Answer:
接口就是提供兩個(gè)不同對(duì)象間的一種連接。
計(jì)算機(jī)程序是通過一組函數(shù)而進(jìn)行連接的,這組函數(shù)就是定義了程序中不同部分的接口。
DLL的接口就是它所輸出的那些函數(shù)。
C++類的接口就是該類的成員函數(shù)集。
COM中的接口是一組由組件實(shí)現(xiàn)的提供給客戶使用的函數(shù)。
在COM中接口是一個(gè)包含函數(shù)
指針數(shù)組
的內(nèi)存結(jié)構(gòu),數(shù)組元素是一個(gè)由組件實(shí)現(xiàn)的函數(shù)地址。
FAQ4:接口的作用是什么?〖第二章〗
Answer:
有了組件如何將它們連接起來構(gòu)成某個(gè)應(yīng)用程序,需要用接口。
在COM中接口就是一切,對(duì)客戶說組件就是接口集,客戶只能通過接口和組件打交道。
說明接口可以保護(hù)系統(tǒng)免受外界變化的影響。這是封裝的體現(xiàn)。
接口實(shí)現(xiàn)了使用戶使用同樣的方式來處理不同的組件。這是多態(tài)的體現(xiàn)。
FAQ5:什么是IUnKnown? 〖第三章〗
Answer:
IUnKnown是一個(gè)接口。
所有COM接口都繼承IUnKnown。
IUnKnown的定義在WIN32 SDK中的UNKNWN頭文件中。
///IUnKnown的定義
interface IUnKnown
{
virtual HRESULT __stdcall QueryInterface(const IID& iid,void **ppv)=0;
virtual ULONG __stdcall AddRef()=0;
virtual ULONG __stdcall Release()=0;
}
FAQ6:QueryInterface函數(shù)的作用是什么?〖第三章〗
Answer:
QueryInterface是IUnKnown的成員函數(shù),客戶可以通過此函數(shù)來查詢組件是否支持某個(gè)特定的接口。
QueryInterface函數(shù)返回一個(gè)指向組件支持的接口的
指針
。
如果QueryInterface函數(shù)沒有找到組件支持的接口則返回
指針
是NULL。
QueryInterface函數(shù)可以使用if…then…else語句、
數(shù)組
、散列表、樹來實(shí)現(xiàn)。
QueryInterface函數(shù)不能使用case語句,因?yàn)镼ueryInterface函數(shù)返回的是一個(gè)HRESULT結(jié)構(gòu)而不是一個(gè)數(shù)。
QueryInterface也是一種無封處理組件版本的機(jī)制。這種機(jī)制使得組件的新舊不同的版本可以互操作。
FAQ7:QueryInterface函數(shù)的實(shí)現(xiàn)規(guī)則是什么?〖第三章〗
Answer:
QueryInterface返回的IUnKnown
指針
總是相同。
若客戶獲得了某個(gè)接口,那么它總能獲得此接口。
客戶可以再次獲得已經(jīng)擁有的接口。
客戶可以返回到起始接口。
若能夠在某個(gè)接口獲得某個(gè)特定接口,那么從任意接口都將可以獲得此接口。
FAQ8:接口的如何實(shí)現(xiàn)?
Answer:
COM接口在C++中是用純抽象基類實(shí)現(xiàn)。
一個(gè)COM組件可以支多個(gè)接口。
一個(gè)C++類可以使用
多重繼承
來實(shí)現(xiàn)一個(gè)支持多個(gè)接口的組件。
組件可以支持任意數(shù)目的接口。
接口應(yīng)該具有不變性。在組件升級(jí)時(shí)應(yīng)該不修改原來的接口,而是添加新的接口。
要精心設(shè)計(jì)實(shí)現(xiàn)接口,以使之能夠支持各種不同的實(shí)現(xiàn)。
FAQ9:QueryInterface函數(shù)的參數(shù)IID是什么?〖第三章〗
Answer:
它是一個(gè)結(jié)構(gòu),接口標(biāo)識(shí)符結(jié)構(gòu)。
IID標(biāo)識(shí)了客戶所需的接口。
每一個(gè)接口都有一個(gè)唯一的接口標(biāo)識(shí)符。所以某個(gè)與IID相對(duì)應(yīng)的接口絕對(duì)不會(huì)發(fā)生變化。
接口IID決定了COM組件的版本。
不同的接口具有不同的ID,包括不同版本的接口。
FAQ10:何時(shí)需要建立一個(gè)新的COM組件版本?〖第三章〗
Answer:
當(dāng)為已有接口指定新的ID時(shí)應(yīng)該是下面的條件至少有一個(gè)成立。
接口中函數(shù)的數(shù)目發(fā)生改變時(shí)。
接口中函數(shù)的順序發(fā)生改變。
接口中某個(gè)函數(shù)的參數(shù)發(fā)生改變
接口中某個(gè)函數(shù)的參數(shù)的順序發(fā)生改變
接口中某個(gè)函數(shù)的參數(shù)的類型發(fā)生改變
接口中函數(shù)的返回值發(fā)生改變
接口中函數(shù)的返回值類型發(fā)生改變
接口中函數(shù)的參數(shù)的含義發(fā)生改變
接口中函數(shù)的含義發(fā)生改變
簡單地說,COM是一種跨應(yīng)用和語言共享
二進(jìn)制代碼
的方法。與C++不同,它提倡
源代碼
重用。ATL便是一個(gè)很好的例證。源碼級(jí)重用雖然好,但只能用于C++。它還帶來了名字沖突的可能性,更不用說不斷拷貝重用代碼而導(dǎo)致工程膨脹和臃腫。
Windows使用DLLs在二進(jìn)制級(jí)共享代碼。這也是Windows程序運(yùn)行的關(guān)鍵——重用kernel32.dll, user32.dll等。但DLLs是針對(duì)C接口而寫的,它們只能被C或理解C調(diào)用規(guī)范的語言使用。由
編程語言
來負(fù)責(zé)實(shí)現(xiàn)共享代碼,而不是由DLLs本身。這樣的話DLLs的使用受到限制。
MFC引入了另外一種MFC擴(kuò)展DLLs二進(jìn)制共享機(jī)制。但它的使用仍受限制——只能在MFC程序中使用。
COM通過定義二進(jìn)制標(biāo)準(zhǔn)解決了這些問題,即COM明確指出二進(jìn)制模塊(DLLs和EXEs)必須被編譯成與指定的結(jié)構(gòu)匹配。這個(gè)標(biāo)準(zhǔn)也確切規(guī)定了在內(nèi)存中如何組織COM對(duì)象。COM定義的二進(jìn)制標(biāo)準(zhǔn)還必須獨(dú)立于任何
編程語言
(如C++中的命名修飾)。一旦滿足了這些條件,就可以輕松地從任何
編程語言
中存取這些模塊。由
編譯器
負(fù)責(zé)所產(chǎn)生的
二進(jìn)制代碼
與標(biāo)準(zhǔn)兼容。這樣使后來的人就能更容易地使用這些
二進(jìn)制代碼
。
在內(nèi)存中,COM對(duì)象的這種標(biāo)準(zhǔn)形式在C++
虛函數(shù)
中偶爾用到,所以這就是為什么許多COM代碼使用C++的原因。但是記住,編寫模塊所用的語言是無關(guān)的,因?yàn)榻Y(jié)果
二進(jìn)制代碼
為所有語言可用。
此外,COM不是Win32特有的。從理論上講,它可以被移植到Unix或其它操作系統(tǒng)。但是我好像還從來沒有在Windows以外的地方聽說過COM。
當(dāng)然COM對(duì)象也需要用過一種特殊的邏輯來從內(nèi)存中釋放對(duì)象。這種方法被稱為COM對(duì)象的引用計(jì)數(shù)。它是用來跟蹤活動(dòng)引用的數(shù)目。當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)為0,對(duì)象從內(nèi)存中刪除。出現(xiàn)這種情況的主要問題是循環(huán)引用。如果存在兩個(gè)COM組件之間的循環(huán)引用,他們會(huì)不會(huì)從內(nèi)存中釋放。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
