【正文】
} 總結(jié): COM接口特點 ?二進(jìn)制特性 ?接口不變性 ?繼承性 (擴(kuò)展性 ) ?多態(tài)性 —— 運(yùn)行過程中的多態(tài)性 。 return 0。 } ULONG CDictionary::Release () { m_Ref 。 ?優(yōu)化 引用計數(shù)問題 ?在整個生存期內(nèi), AddRef與 Release一定要配對,否則: –漏掉 AddRef, 程序出錯 –漏掉 Release, 對象永不釋放 引用計數(shù)實現(xiàn)舉例 ULONG CDictionary::AddRef () { m_Ref ++。 使用引用計數(shù)規(guī)則 ?函數(shù)參數(shù) –輸入?yún)?shù) –輸出參數(shù) –輸入 輸出參數(shù) ?局部接口指針變量 ?全局接口指針變量 ?類成員變量 使用引用計數(shù)規(guī)則(續(xù)) ?一般性規(guī)則 –在順序執(zhí)行過程中,如果要對一個接口指針變量賦值,則對賦值后的接口指針變量調(diào)用AddRef, 并且,如果賦值前的接口指針變量還沒有結(jié)束,則賦值前必須對它調(diào)用 Release以便先結(jié)束它的使用。 pIDictionaryForWord Release ( )。 // Insert or delete some word pIDictionaryForWord InsertWord(...,...)。 } ...... IDictionary *pIDictionaryForWord = pIDictionary。 if (retValue == FALSE) { pIDictionaryRelease()。 return (ULONG) m_Ref。 return (ULONG) m_Ref。 引用計數(shù)實現(xiàn)示例 (續(xù) ) CDictionary::CDictionary () { m_Ref = 0。 int m_Ref 。 // …… private : struct DictWord *m_pData。 virtual BOOL Initialize()。 virtual ULONG AddRef() 。 public : virtual HRESULT QueryInterface(const IIDamp。對象引用計數(shù)IUn k n o w n接口引用計數(shù)接口引用計數(shù)接口引用計數(shù)實現(xiàn)引用計數(shù)三種方案 ?組件級 –計數(shù)分辨率太粗 ?對象級 ?接口級 –計數(shù)分辨率太細(xì) 引用計數(shù)實現(xiàn)示例 class CDictionary : public IDictionary { public : CDictionary()。 } return S_OK。 } else { *ppv = NULL。 } else if ( iid == IID_SpellCheck ) { *ppv = static_castISpellCheck * this 。 } else if ( iid == IID_Dictionary ) { *ppv = static_castIDictionary *this 。 iid, void **ppv) { if ( iid == IID_IUnknown ) { *ppv = static_castIDictionary *this 。 ...... }。 virtual ULONG Release() 。 iid, void **ppv) 。 ~CDictionary()。 pISpellCheck Release ( )。 return。pISpellCheck)。 } ...... ISpellCheck *pISpellCheck。 if (retValue == FALSE) { pIDictionaryRelease()。 COM接口的內(nèi)存模型 (續(xù)二 ) 字典對象 1 的接口指針 p IDi ctio n ary 1 字典對象 2 的接口指針 p IDi ctio n ary 2 p V tab le Qu ery In terf ac e A d d Ref ...... CDi ctio n ary 類中虛函數(shù)的具體實現(xiàn) v t ab l e m _p D at a m _ Dict F il en am e p V tab le 字典數(shù)據(jù) ...... Qu ery In te rf ac e A d d Ref ...... 另一個字典對象類中虛函數(shù)的具體實現(xiàn) v t ab l e 接口查詢 ?目的:按照 COM規(guī)范,一個 COM對象可以實現(xiàn)多個接口。 COM接口的內(nèi)存模型 (續(xù)一 ) 客戶使用的 接口指針 p ID ic tio n a ry 1 p ID ic tio n a ry 2 p V ta b le Q u e ry In te rf a c e A d d Re f Re le a se In itializ e CD ic tio n a ry 類中虛函數(shù)的具體實現(xiàn) v t abl e m _pD at a m _ D ic tF ilen a m e p V ta b le m _pD at a m _ D ic tF ilen a m e 。 I D i ct i onary v t abl e t hi s COM接口的內(nèi)存模型 客戶使用的 接口指針 p ID ic tio n a ry p V ta b le Q u e ry In te rf a c e A d d Re f Re le a se In itializ e CD ic tio n a ry 類中虛函數(shù)的具體實現(xiàn) v t abl e m _pD at a m _ D ic tF ilen a m e 。 BO OL Res to reL ib rary (th is * , S tri n g )。 v o id Dele teW o rd )( th is * , S tri n g )。 BO OL In it ialize (th is * ) BO OL L o a d L ib rary (th is * , S tri n g )。 pV t abl e HR E S UL T Qu e ry In terf a c e ( … ) UL ONG A d d Ref ()。 virtual void FreeLibrary() = 0。 virtual BOOL LookupWord(String, String *) = 0。 virtual BOOL InsertWord(String, String) = 0。 C++語言描述示例 — IDictionary class IDictionary : public IUnknown { virtual BOOL Initialize() = 0。 void (*FreeLibrary)( IDictionary * this)。 BOOL (*LookupWord)( IDictionary * this, String, String *)。 BOOL (*InsertWord)( IDictionary * this, String, String)。 struct IDictionaryVtbl { /* … QueryInterface, AddRef, Release */ BOOL (*Initialize)( IDictionary * this)。 struct IDictionary { IDictionaryVtbl * pVtbl。 }。 } IUnknownVtbl。 ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( IUnknown __RPC_FAR * This)。 }。 virtual ULONG __stdcall AddRef() = 0。 IUnknown接口 ?所有的 COM接口都從 IUnknown派生 ?C++定義: class IUnknown { public: virtual HRESULT__stdcall QueryInterface( const IIDamp。 } GUID。 WORD Data3。 其他尚待考慮的問題 ?Dll什么時候被卸載? ?如何標(biāo)識一個接口?字符串? ?線程安全? ?如何標(biāo)識一個對象?對象的身份? ?跨進(jìn)程?跨機(jī)器?對象環(huán)境? ?…… COM接口 ?概念:函數(shù)集,以二進(jìn)制的形式給出了從一方到另一方的調(diào)用規(guī)范 ?接口標(biāo)識 —— IID ?IUnknown ?COM接口二進(jìn)制結(jié)構(gòu) COM接口的標(biāo)識 —— IID ?是 GUID的一種用法 ? GUID是一個 128位的長整數(shù) ?產(chǎn)生規(guī)則保證了唯一性 ?例子: {54BF6567100711D1B0AA444553540000} ? C語言結(jié)構(gòu)和定義: