1 概述
這裡講的不是COM的實現原理,而是工作原理。即COM組件是如何工作,整個生命周期是如何的。這裡只講述兩種COM組件,即進程內組件和本地組件。
2 知識基礎
動態連結庫(Dynamic-Link Library)DLL。
Windows系統的進程-線程模型。
3 兩個角度看COM組件
從調用者(功能使用者)的角度來看COM組件,COM組件是一個抽象的功能對象。你知道它提供了什麼功能,但是不需要知道它在哪裡提供這些功能的,反正系統會將功能交到你手上。
反過來從實現者(功能提供者)的角度來看就不一樣了,你還是要選擇一下到時候調用者如何使用你的功能的。一般就是選擇你的對象要不要放到調用者的進程中去。而一般的選擇就是和調用者共用一個進程,這樣線程關係比較簡單,調用速度也高。只有特殊的情況下才獨立進程,例如做大的系統擔心互相影響、或者實現者的生命周期不能被調用者局限、實現者需要做系統單例等情況。
本文檔就是寫一下調用COM組件的整個流程的簡單描述,大家有個大概的認識,方便大家開發實現者。
4 進程內COM組件
所謂進程內COM組件,就是對象創建於調用者進程中的組件,英文名稱In-process Server。其形態一般為DLL或OCX。其註冊方法是regsvr32(手工),DllRegisterServer(程序),vsdrpCOMSelfReg(安裝)。其原理如圖所示。
5 本地COM組件
所謂本地COM組件,就是對象創建於與調用者進程同一個系統之中的不同進程之中的組件,英文名稱Local Server。其註冊方法是帶「/regserver」運行(手工/程序),vsdrpCOMSelfReg(安裝)。其形態一般為EXE。其原理如圖所示。
6 ATL組件
不管是進程內ATL組件還是本地ATL組件,都是按照COM組件的原理,或者說被調用的機制的來實現。具體運行邏輯參見上圖,可以看到和COM調用原理一一對應。
在VISIO繪圖裡面沒有說明需要在這裡補充的是,各個子功能的實現,如類工廠、類型列表、對象引用、對象與模塊類引用計數掛鈎、對象信息維護等的實現。一言以蔽之,就是模板類(注意,不是模塊類)和代碼插入。
ATL7.1開發中,COM對象的類聲明前面會有COM類屬性聲明,根據COM類屬性聲明(如coclass),ATL會在編譯前插入若干代碼來實現各種COM框架需要的功能。如根據類的定義插入類工廠的實現,將類的信息放在類型列表的初始化,讓類派生於CComObjectRootEx實現對象信息維護。在類工廠的實現中使用CComObject等類型來實現對象引用計數,對象與模板類引用計數掛鈎。
這就是ATL7.1(注意,ATL6.0不是)的精髓,將各種基礎類做成模板,使用代碼插入時就根據COM對象聲明選擇合適的模板參數。與MFC的ClassWizard相比,因為開發者看不到插入的框架代碼,所以無法修改。雖然有個開發靈活性不足的缺點,但是框架穩定性大大加強。