什麼是COM組件

COM是Component Object Model (組件對象模型)的縮寫。
 

 

  用戶需要什麼樣的軟件產品?這是一個多選題,但高效,健壯是肯定會被選種的。作爲一名軟件開發人員如何做才能滿足用戶的需要呢?必須要保證升級應用時不破壞與以前版本的向後兼容性。必須做到擴展系統服務時不依賴特定的操作系統。面向對象的程序設計顯然是一次革命性的改變。採用面向對象的設計方法我們可以很容易的把要解決的問題事物抽象成各種類,並將內部動作封裝隱藏起來,只提供一些接口。但這並沒有完全解決我們的問題。昨天我在《程序員》雜誌上看到,現在是後OO時代,那OO以後是什麼呢?應該是面向組件吧。
 

 

  雷神剛剛讀完《COM技術內幕》一書,整理了一個FAQ,供大家在學習此書時參考。
 

 

  這是第一部分,包含前3章的內容。
 

 

  FAQ1:什麼是COM組件?〖第一章〗
 

 

  FAQ2:組件不是……?〖第一章〗
 

 

  FAQ3:什麼是接口?〖第二章〗
 

 

  FAQ4:接口的作用是什麼?〖第二章〗
 

 

  FAQ5:什麼是IUnKnown? 〖第三章〗
 

 

  FAQ6:QueryInterface函數的作用是什麼?〖第三章〗
 

 

  FAQ7:QueryInterface函數的實現規則是什麼?〖第三章〗
 

 

  FAQ8:QueryInterface的樣子?〖第三章〗
 

 

  FAQ9:QueryInterface函數的參數IID是什麼?〖第三章〗
 

 

  FAQ10:何時需要建立一個新的COM組件版本?〖第三章〗
 

 

  Question:
 

 

  什麼是COM組件?
 

 

  Answer:
 

 

  COM組件是以WIN32動態鏈接庫(DLL)或可執行文件(EXE)形式發佈的可執行代碼組成。
 

 

  COM組件是遵循COM規範編寫的
 

 

  COM組件是一些小的二進制可執行文件
 

 

  COM組件可以給應用程序、操作系統以及其他組件提供服務
 

 

  自定義的COM組件可以在運行時刻同其他組件連接起來構成某個應用程序
 

 

  COM組件可以動態的插入或卸出應用
 

 

  COM組件必須是動態鏈接的
 

 

  COM組件必須隱藏(封裝)其內部實現細節
 

 

  COM組件必須將其實現的語言隱藏
 

 

  COM組件必須以二進制的形式發佈
 

 

  COM組件必須可以在不妨礙已有用戶的情況下被升級
 

 

  COM組件可以透明的在網絡上被重新分配位置
 

 

  COM組件按照一種標準的方式來宣佈它們的存在
 

 

  Question:
 

 

  組件不是……?
 

 

  Answer:
 

 

  COM組件不是一種計算機語言
 

 

  COM組件不是DLL,只是利用DLL來給組件提供動態鏈接的能力
 

 

  COM組件不是一個API函數集。
 

 

  COM組件不是類
 

 

  Question:
 

 

  什麼是接口?
 

 

  Answer:
 

 

  接口就是提供兩個不同對象間的一種連接。
 

 

  計算機程序是通過一組函數而進行連接的,這組函數就是定義了程序中不同部分的接口。
 

 

  DLL的接口就是它所輸出的那些函數。
 

 

  C++類的接口就是該類的成員函數集。
 

 

  COM中的接口是一組由組件實現的提供給客戶使用的函數。
 

 

  在COM中接口是一個包含函數指針數組的內存結構,數組元素是一個由組件實現的函數地址。
 

 

  Question:
 

 

  接口的作用是什麼?
 

 

  Answer:
 

 

  有了組件如何將它們連接起來構成某個應用程序,需要用接口。
 

 

  在COM中接口就是一切,對客戶說組件就是接口集,客戶只能通過接口和組件打交道。
 

 

  說明接口可以保護系統免受外界變化的影響。這是封裝的體現。
 

 

  接口實現了使用戶使用同樣的方式來處理不同的組件。這是多態的體現。
 

 

  Question:
 

 

  接口的如何實現?
 

 

  Answer:
 

 

  COM接口在C++中是用純抽象基類實現。
 

 

  一個COM組件可以支多個接口。
 

 

  一個C++類可以使用多重繼承來實現一個支持多個接口的組件。
 

 

  組件可以支持任意數目的接口。
 

 

  接口應該具有不變性。在組件升級時應該不修改原來的接口,而是添加新的接口。
 

 

  要精心設計實現接口,以使之能夠支持各種不同的實現。
 

 

  Question:
 

 

  什麼是IUnKnown?
 

 

  Answer:
 

 

  IUnKnown是一個接口。
 

 

  所有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;
 

 

  }
 

 

  Question:
 

 

  QueryInterface函數的作用是什麼?
 

 

  Answer:
 

 

  QueryInterface是IUnKnown的成員函數,客戶可以通過此函數來查詢組件是否支持某個特定的接口。
 

 

  QueryInterface函數返回一個指向組件支持的接口的指針。
 

 

  如果QueryInterface函數沒有找到組件支持的接口則返回指針是NULL。
 

 

  QueryInterface函數可以使用if…then…else語句、數組、散列表、樹來實現。
 

 

  QueryInterface函數不能使用case語句,因爲QueryInterface函數返回的是一個HRESULT結構而不是一個數。
 

 

  QueryInterface也是一種無封處理組件版本的機制。這種機制使得組件的新舊不同的版本可以互操作。
 

 

  Question:
 

 

  QueryInterface函數的實現規則是什麼?
 

 

  Answer:
 

 

  QueryInterface返回的IUnKnown指針總是相同。
 

 

  若客戶獲得了某個接口,那麼它總能獲得此接口。
 

 

  客戶可以再次獲得已經擁有的接口。
 

 

  客戶可以返回到起始接口。
 

 

  若能夠在某個接口獲得某個特定接口,那麼從任意接口都將可以獲得此接口。
 

 

  Question:
 

 

  QueryInterface函數的參數IID是什麼?
 

 

  Answer:
 

 

  它是一個結構,接口標識符結構。
 

 

  IID標識了客戶所需的接口。
 

 

  每一個接口都有一個唯一的接口標識符。所以某個與IID相對應的接口絕對不會發生變化。
 

 

  接口IID決定了COM組件的版本。
 

 

  不同的接口具有不同的ID,包括不同版本的接口。
 

 

  Question:
 

 

  何時需要建立一個新的COM組件版本?
 

 

  Answer:
 

 

  當爲已有接口指定新的ID時應該是下面的條件至少有一個成立。
 

 

  接口中函數的數目發生改變時。
 

 

  接口中函數的順序發生改變。
 

 

  接口中某個函數的參數發生改變
 

 

  接口中某個函數的參數的順序發生改變
 

 

  接口中某個函數的參數的類型發生改變
 

 

  接口中函數的返回值發生改變
 

 

  接口中函數的返回值類型發生改變
 

 

  接口中函數的參數的含義發生改變
 

 

  接口中函數的含義發生改變
 

 

  簡單地說,COM是一種跨應用和語言共享二進制代碼的方法。與C++不同,它提倡源代碼重用。ATL便是一個很好的例證。源碼級重用雖然好,但只能用於C++。它還帶來了名字衝突的可能性,更不用說不斷拷貝重用代碼而導致工程膨脹和臃腫。
 

 

  Windows使用DLLs在二進制級共享代碼。這也是Windows程序運行的關鍵——重用kernel32.dll, user32.dll等。但DLLs是針對C接口而寫的,它們只能被C或理解C調用規範的語言使用。由編程語言來負責實現共享代碼,而不是由DLLs本身。這樣的話DLLs的使用受到限制。
 

 

  MFC引入了另外一種MFC擴展DLLs二進制共享機制。但它的使用仍受限制——只能在MFC程序中使用。
 

 

  COM通過定義二進制標準解決了這些問題,即COM明確指出二進制模塊(DLLs和EXEs)必須被編譯成與指定的結構匹配。這個標準也確切規定了在內存中如何組織COM對象。COM定義的二進制標準還必須獨立於任何編程語言(如C++中的命名修飾)。一旦滿足了這些條件,就可以輕鬆地從任何編程語言中存取這些模塊。由編譯器負責所產生的二進制代碼與標準兼容。這樣使後來的人就能更容易地使用這些二進制代碼。
 

 

  在內存中,COM對象的這種標準形式在C++虛函數中偶爾用到,所以這就是爲什麼許多COM代碼使用C++的原因。但是記住,編寫模塊所用的語言是無關的,因爲結果二進制代碼爲所有語言可用。
 

 

  此外,COM不是Win32特有的。從理論上講,它可以被移植到Unix或其它操作系統。但是我好像還從來沒有在Windows以外的地方聽說過COM。

  COM+特性
 

 

  與COM一樣,COM+基於二進制組件和基於接口的編程。通過使用透明RPC層,可以跨越進程和計算機邊界進行遠程方法調用。正如COM組件那樣,COM+組件可以在成品中升級和擴展,而不會對使用它們的客戶端應用程序造成負面影響。
 

 

  與MTS一樣,COM+支持分佈式事務和基於角色的安全性。它提供內置線程池方案,該方案與MTS的線程池方案一樣透明。COM+編程模型同樣利用偵聽通過聲明性屬性向開發人員公開平臺服務。但是,COM+比MTS更進一步地利用了基於屬性的編程。除了事務性服務和集成安全性外,COM+還公開自定義對象構造、同步、對象池等服務。COM+的其他新功能(如排隊組件和COM+事件)也通過可配置的屬性公開。
 

 

  COM+並不是COM的新版本,我們可以把它理解爲COM的新發展,或者爲COM更高層次上的應用。COM+的底層結構仍然以COM爲基礎,它幾乎包容了COM的所有內容。有一種說法這樣認爲,COM+是COM、DCOM和MTS(MicrosoftTransactionServer)的集成,這種說法有一定的道理,因爲COM+確實綜合了這些技術要素。但更重要的一點是,COM+倡導了一種新的概念,它把COM組件軟件提升到應用層而不再是底層的軟件結構,它通過操作系統的各種支持,使組件對象模型建立在應用層上,把所有組件的底層細節留給操作系統。
 

 

  COM是個開放的組件標準,它有很強的擴充和擴展能力,從COM到DCOM,再到MTS的發展過程也充分說明了這一點。對COM有使用經驗的讀者一定可以感覺到,雖然COM已經改變了Windows程序員的應用開發模式,把組件的概念融入到Windows應用中,但是由於種種原因,DCOM和MTS的許多優越性還沒有爲廣大的Windows程序員所認識。MTS針對企業應用和Web應用的特點,在COM/DCOM的基礎上又添加了許多功能和特性,包括事務特性、安全模型、管理和配置等,MTS使COM成爲一個完整的組件體系結構。由於歷史的原因,COM、DCOM和MTS相互之間並不很融洽,難以形成統一的整體,不過,這種狀況很快就要結束,因爲COM+將把這三者有效地統一起來,形成一個全新的、功能強大的組件體系結構,並且把DCOM和MTS的各種優勢以更爲簡捷的方式帶給Windows2000程序員和用戶。
 

 

  COM+不再侷限於COM的組件技術,它更加註重於分佈式網絡應用的設計和實現,已經成爲Microsoft系統平臺策略和軟件發展策略的一部分。COM+繼承了COM幾乎全部的優勢,同時又避免了COM實現方面的一些不足。COM+緊緊地與操作系統結合起來,通過系統服務爲應用程序提供全面的服務。
 

 

  COM組件類型
 

 

  進程內組件:組件是在主調應用程序的進程範圍內運行,是以DLL方式實現的。組件的實現是快速的,但由於和應用程序公用一個進程,導致了不安全的因素。
 

 

  進程外組件:它又可分爲兩類。本地服務器進程組件,它是組件與調用組件者在同一機器上;遠程服務器進程組件,它是組件使用遠程過程調用RPCs和客戶應用程序進行通信。

發佈了27 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章