高級(jí)軟件(COM基礎(chǔ):接口及實(shí)現(xiàn))_第1頁(yè)
高級(jí)軟件(COM基礎(chǔ):接口及實(shí)現(xiàn))_第2頁(yè)
高級(jí)軟件(COM基礎(chǔ):接口及實(shí)現(xiàn))_第3頁(yè)
高級(jí)軟件(COM基礎(chǔ):接口及實(shí)現(xiàn))_第4頁(yè)
高級(jí)軟件(COM基礎(chǔ):接口及實(shí)現(xiàn))_第5頁(yè)
已閱讀5頁(yè),還剩49頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、1構(gòu)件對(duì)象模型構(gòu)件對(duì)象模型:COM高級(jí)軟件工程2基礎(chǔ)部分基礎(chǔ)部分綜述綜述接口接口實(shí)現(xiàn)實(shí)現(xiàn)高級(jí)部分高級(jí)部分包含與聚合包含與聚合COM與與VC自動(dòng)化自動(dòng)化DCOM高級(jí)軟件工程3(1) COM的起源的起源 源于源于OLE: Object Link and Embedding OLE1 采用采用DDE(Dynamic Data Exchange) 在不同的程序之間進(jìn)行通信在不同的程序之間進(jìn)行通信DDE缺點(diǎn)缺點(diǎn): 效率低效率低,穩(wěn)定性不好穩(wěn)定性不好,使用不方便使用不方便 COM是為克服上述不足而出現(xiàn)的是為克服上述不足而出現(xiàn)的 OLE2 以以 COM 為基礎(chǔ)為基礎(chǔ) 但但OLE未能體現(xiàn)未能體現(xiàn)COM優(yōu)點(diǎn)優(yōu)點(diǎn)

2、 1 綜述綜述4(2)什么是什么是COM 構(gòu)件對(duì)象模型構(gòu)件對(duì)象模型:Component Object Model 客戶與構(gòu)件為了能夠互操作而遵循的標(biāo)準(zhǔn)客戶與構(gòu)件為了能夠互操作而遵循的標(biāo)準(zhǔn) COM標(biāo)準(zhǔn)包括規(guī)范與實(shí)現(xiàn)兩部分標(biāo)準(zhǔn)包括規(guī)范與實(shí)現(xiàn)兩部分規(guī)范部分定義了構(gòu)件之間的通信機(jī)制規(guī)范部分定義了構(gòu)件之間的通信機(jī)制這些規(guī)范不依賴于任何特定的語(yǔ)言這些規(guī)范不依賴于任何特定的語(yǔ)言和操作系統(tǒng)和操作系統(tǒng)實(shí)現(xiàn)部分即實(shí)現(xiàn)部分即COM庫(kù)庫(kù)為為COM規(guī)范的具體實(shí)現(xiàn)提供一些核心服務(wù)規(guī)范的具體實(shí)現(xiàn)提供一些核心服務(wù)高級(jí)軟件工程5(3) COM構(gòu)件構(gòu)件以以 DLL或或EXE形式發(fā)布的代碼形式發(fā)布的代碼與語(yǔ)言無(wú)關(guān)與語(yǔ)言無(wú)關(guān)以二進(jìn)制

3、形式發(fā)布以二進(jìn)制形式發(fā)布可以在不妨礙客戶的形式下被升級(jí)可以在不妨礙客戶的形式下被升級(jí)可以透明地在網(wǎng)絡(luò)上被重新分配可以透明地在網(wǎng)絡(luò)上被重新分配構(gòu)件與類構(gòu)件與類:一個(gè)構(gòu)件可以由多個(gè)類實(shí)現(xiàn)一個(gè)構(gòu)件可以由多個(gè)類實(shí)現(xiàn)接口與類接口與類:一個(gè)類可以實(shí)現(xiàn)多個(gè)接口一個(gè)類可以實(shí)現(xiàn)多個(gè)接口6(4) COM庫(kù)庫(kù) (COM Library)功能功能: (1)實(shí)現(xiàn)客戶方與服務(wù)器方實(shí)現(xiàn)客戶方與服務(wù)器方COM應(yīng)用的創(chuàng)建過(guò)程應(yīng)用的創(chuàng)建過(guò)程(2)COM通過(guò)注冊(cè)表查找本地服務(wù)器通過(guò)注冊(cè)表查找本地服務(wù)器(即即EXE程序程序) 以及程序名與以及程序名與CLSID的轉(zhuǎn)換的轉(zhuǎn)換(3)提供標(biāo)準(zhǔn)的內(nèi)存控制方法提供標(biāo)準(zhǔn)的內(nèi)存控制方法DCOM的實(shí)

4、現(xiàn)提供了分布式環(huán)境下的通信機(jī)制的實(shí)現(xiàn)提供了分布式環(huán)境下的通信機(jī)制在操作系統(tǒng)層次在操作系統(tǒng)層次 以以DLL文件的形式存在文件的形式存在高級(jí)軟件工程7(5) COM特性特性語(yǔ)言無(wú)關(guān)性語(yǔ)言無(wú)關(guān)性為跨語(yǔ)言合作開(kāi)發(fā)提供了統(tǒng)一標(biāo)準(zhǔn)為跨語(yǔ)言合作開(kāi)發(fā)提供了統(tǒng)一標(biāo)準(zhǔn)并得到不同集成開(kāi)發(fā)環(huán)境的支持并得到不同集成開(kāi)發(fā)環(huán)境的支持 進(jìn)程透明性進(jìn)程透明性進(jìn)程內(nèi)服務(wù)程序進(jìn)程內(nèi)服務(wù)程序: DLL本地服務(wù)程序本地服務(wù)程序: EXE遠(yuǎn)地服務(wù)程序遠(yuǎn)地服務(wù)程序: DLL或或EXE實(shí)現(xiàn)進(jìn)程透明性的關(guān)鍵是實(shí)現(xiàn)進(jìn)程透明性的關(guān)鍵是COM庫(kù)庫(kù)它負(fù)責(zé)服務(wù)體的定位它負(fù)責(zé)服務(wù)體的定位 管理對(duì)象的創(chuàng)建及對(duì)象與客戶之間的通信管理對(duì)象的創(chuàng)建及對(duì)象與客戶之間

5、的通信復(fù)用性復(fù)用性包含方式包含方式 聚合方式聚合方式8(6) COM發(fā)展趨勢(shì)發(fā)展趨勢(shì)操作系統(tǒng)操作系統(tǒng) 成為系統(tǒng)的基本軟件模型成為系統(tǒng)的基本軟件模型數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù) OLE DB/ADO 以以 COM 的方式的方式為數(shù)據(jù)訪問(wèn)提供一致的接口為數(shù)據(jù)訪問(wèn)提供一致的接口Internet ActiveX包含了所有基于包含了所有基于COM的的Internet相關(guān)技術(shù)相關(guān)技術(shù)COM+增加增加MTS等服務(wù)等服務(wù)高級(jí)軟件工程92 COM接口接口COM接口是接口是COM規(guī)范的核心內(nèi)容規(guī)范的核心內(nèi)容接口的意義接口的意義(略略)一個(gè)接口包含了一組函數(shù)一個(gè)接口包含了一組函數(shù)在在C+中中, 可以用抽象基類來(lái)定義可以用抽象基類來(lái)

6、定義COM接口接口接口的實(shí)現(xiàn)接口的實(shí)現(xiàn) : vtbl 指針指針 虛擬函數(shù)表虛擬函數(shù)表10Vtbl指針指針虛擬函數(shù)表虛擬函數(shù)表pIX接口的內(nèi)存結(jié)構(gòu)接口的內(nèi)存結(jié)構(gòu)IX&Fx1&Fx2&Fx3&Fx4高級(jí)軟件工程11Vtbl的作用的作用:提高接口實(shí)現(xiàn)的靈活性提高接口實(shí)現(xiàn)的靈活性例子例子:一個(gè)實(shí)現(xiàn)接口一個(gè)實(shí)現(xiàn)接口IX的類的類CA,CA包含包含2個(gè)數(shù)據(jù)個(gè)數(shù)據(jù):Vtbl指針指針虛擬函數(shù)表虛擬函數(shù)表IX&Fx1&Fx2&Fx3&Fx4Data1Data2pAFx1Fx2Fx3Fx4CA12兩個(gè)實(shí)例兩個(gè)實(shí)例 共享同一共享同一Vtbl:Vtbl指針指針虛擬函數(shù)表虛擬函數(shù)表&Fx1&Fx2&Fx3&Fx4Data

7、1Data2pA1pA2Fx1Fx2Fx3Fx4CAVtbl指針指針Data1Data2高級(jí)軟件工程13 接口特點(diǎn)接口特點(diǎn)實(shí)現(xiàn)級(jí)實(shí)現(xiàn)級(jí)二進(jìn)制,獨(dú)立于編程語(yǔ)言二進(jìn)制,獨(dú)立于編程語(yǔ)言穩(wěn)定性穩(wěn)定性客戶與服務(wù)器依賴于接口客戶與服務(wù)器依賴于接口繼承性繼承性便于擴(kuò)展接口便于擴(kuò)展接口, 不提倡繼承不提倡繼承所有接口皆繼承所有接口皆繼承Iunknown)多態(tài)性:多態(tài)性:14(1)功能)功能提供:提供:生存期控制生存期控制接口查詢接口查詢 IUnknown的定義(的定義(IDL):):interface IUnkownvirtual HRESULT QueryInterface(const IID&, void

8、 *ppv) = 0;virtual ULONG AddRef() = 0;virtual ULONG Release() = 0;高級(jí)軟件工程15Vtbl指針指針虛擬函數(shù)表虛擬函數(shù)表IXQueryInterfaceAddRefRelease&FxpAQueryInterfaceAddRefReleaseFxCA所有接口都必須繼承所有接口都必須繼承IUnknown16IUnknown指針的獲取指針的獲取 IUnknown * CreateInstance();創(chuàng)建構(gòu)件時(shí),客戶可以使用創(chuàng)建構(gòu)件時(shí),客戶可以使用CreateInstance, 而不是而不是new。CreateInstance的定義:

9、的定義: IUnknown * CreateInstance() IUnknown * pI = static_cast (new foo); pI - AddRef(); return pI; 高級(jí)軟件工程17AddRef與與Release控制構(gòu)件的生命期控制構(gòu)件的生命期解決內(nèi)存管理問(wèn)題解決內(nèi)存管理問(wèn)題使構(gòu)件能夠自己將自己刪除使構(gòu)件能夠自己將自己刪除使用規(guī)則使用規(guī)則返回接口指針之前調(diào)用返回接口指針之前調(diào)用 AddRef;使用完接口之后調(diào)用使用完接口之后調(diào)用Release;賦值之后調(diào)用賦值之后調(diào)用AddRef;18引用計(jì)數(shù)的實(shí)現(xiàn)方式引用計(jì)數(shù)的實(shí)現(xiàn)方式:在什么層次上進(jìn)行計(jì)數(shù)在什么層次上進(jìn)行計(jì)數(shù)構(gòu)

10、件構(gòu)件對(duì)象對(duì)象接口接口構(gòu)件構(gòu)件構(gòu)件引用記數(shù)構(gòu)件引用記數(shù)對(duì)象引用記數(shù)對(duì)象引用記數(shù)對(duì)象引用記數(shù)對(duì)象引用記數(shù)對(duì)象對(duì)象1對(duì)象對(duì)象2接口接口接口接口接口接口接口接口接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)接口引用記數(shù)高級(jí)軟件工程19一個(gè)一個(gè)COM對(duì)象(構(gòu)件)可以實(shí)現(xiàn)多個(gè)接口對(duì)象(構(gòu)件)可以實(shí)現(xiàn)多個(gè)接口使用使用QueryInterface查詢某個(gè)構(gòu)件是否支持某個(gè)特定的接口查詢某個(gè)構(gòu)件是否支持某個(gè)特定的接口 void foo(Iunknown * pI)/Define a pointer for the interface.IX * pIX = NULL;/Ask

11、 for nterface IXHRESULT hr = pI-QueryUbterface(IID_IX, (void *)&pIX);/Check return value.If (SUCCEEDED(hr) / Use interfacepIX-Fx();20 假定存在類假定存在類 CA,繼承接口繼承接口 IX 與與 IY: HRESULT _sfdcall CA: QueryInterface(const IID& iid, void * ppv) if (iid = IID_IUnknown) *ppv = static_cast(this); else if (iid = IID_

12、IX) *ppv = static_cast(this); else if (iid = IID_IY) *ppv = static_cast(this);else *ppv = NULL; return E_NOINTERFACE;static_cast(*ppv)-AddRef();return S_OK;高級(jí)軟件工程21QueryInterface返回的總是同一個(gè)返回的總是同一個(gè)IUnknown指針指針若客戶曾經(jīng)獲取過(guò)某個(gè)接口若客戶曾經(jīng)獲取過(guò)某個(gè)接口,那么它將總能獲取此接口那么它將總能獲取此接口客戶可以再次獲取已經(jīng)擁有的接口客戶可以再次獲取已經(jīng)擁有的接口客戶可以返回到起始接口客戶可以返回

13、到起始接口若能夠從某個(gè)接口獲取某特定接口若能夠從某個(gè)接口獲取某特定接口則可以從則可以從(該構(gòu)件的該構(gòu)件的)任意接口獲取此接口任意接口獲取此接口22COM接口永遠(yuǎn)不會(huì)變化接口永遠(yuǎn)不會(huì)變化 :一個(gè)一個(gè)IID就是一個(gè)接口就是一個(gè)接口 通過(guò)發(fā)行新版本構(gòu)件解決兼容性通過(guò)發(fā)行新版本構(gòu)件解決兼容性當(dāng)下列條件中的任何一個(gè)變化時(shí)當(dāng)下列條件中的任何一個(gè)變化時(shí)應(yīng)給新接口指定新應(yīng)給新接口指定新IID:接口中函數(shù)數(shù)目接口中函數(shù)數(shù)目接口中函數(shù)順序接口中函數(shù)順序某個(gè)函數(shù)的參數(shù)某個(gè)函數(shù)的參數(shù)某個(gè)函數(shù)參數(shù)的順序某個(gè)函數(shù)參數(shù)的順序某個(gè)函數(shù)參數(shù)的類型某個(gè)函數(shù)參數(shù)的類型函數(shù)可能的返回值函數(shù)可能的返回值函數(shù)返回值的類型函數(shù)返回值的類型

14、等等不同版本接口的命名不同版本接口的命名:在老名稱后加一個(gè)數(shù)字在老名稱后加一個(gè)數(shù)字23(1)預(yù)備知識(shí)預(yù)備知識(shí):DLLDLL是一個(gè)構(gòu)件服務(wù)器是一個(gè)構(gòu)件服務(wù)器EXE也可以是構(gòu)件服務(wù)器也可以是構(gòu)件服務(wù)器使用戶在應(yīng)用程序的運(yùn)行過(guò)程中替換構(gòu)件使用戶在應(yīng)用程序的運(yùn)行過(guò)程中替換構(gòu)件構(gòu)件是構(gòu)件是DLL中實(shí)現(xiàn)的接口集中實(shí)現(xiàn)的接口集DLL共享它們所鏈入的應(yīng)用程序地址空間共享它們所鏈入的應(yīng)用程序地址空間HRESULT向用戶報(bào)告構(gòu)件運(yùn)行結(jié)果狀況向用戶報(bào)告構(gòu)件運(yùn)行結(jié)果狀況“Here is the RESULT”WINERROR.H中進(jìn)行定義中進(jìn)行定義用戶可以定義自己的代碼用戶可以定義自己的代碼24GUID: Globa

15、lly Unique IDentifier用于標(biāo)識(shí)構(gòu)件用于標(biāo)識(shí)構(gòu)件(CLSID)與接口與接口(IID)128位位(長(zhǎng)整數(shù)長(zhǎng)整數(shù))由于空間足夠大由于空間足夠大 接口標(biāo)識(shí)沖突較小接口標(biāo)識(shí)沖突較小可以用編程的方法生成具有唯一性的可以用編程的方法生成具有唯一性的GUIDVC: UUIDGEN.EXE, GUIDGEN.EXE借鑒了借鑒了OSF的的UUID(DCE中的中的RPC使用使用).對(duì)對(duì)GUID值的傳遞通常通過(guò)引用進(jìn)行值的傳遞通常通過(guò)引用進(jìn)行CLSID:CLaSs IDentifier25Windows 注冊(cè)表注冊(cè)表Windows操作系統(tǒng)的共享系統(tǒng)數(shù)據(jù)庫(kù)操作系統(tǒng)的共享系統(tǒng)數(shù)據(jù)庫(kù)包括包括 硬件硬件

16、軟件軟件 配置及用戶等各種信息配置及用戶等各種信息由由REGEDIT.EXE (95/98) REGEDIT32.EXE(NT) 啟動(dòng)啟動(dòng)可以使用可以使用REGSVR32.EXE來(lái)注冊(cè)某個(gè)構(gòu)件來(lái)注冊(cè)某個(gè)構(gòu)件注冊(cè)表是一個(gè)由許多元素構(gòu)成的層次結(jié)構(gòu)注冊(cè)表是一個(gè)由許多元素構(gòu)成的層次結(jié)構(gòu)每一個(gè)元素均被稱作是一個(gè)關(guān)鍵字每一個(gè)元素均被稱作是一個(gè)關(guān)鍵字每一個(gè)關(guān)鍵字可以包含一系列子關(guān)鍵字等每一個(gè)關(guān)鍵字可以包含一系列子關(guān)鍵字等 例如:例如:HKEY_CLASSES_ROOTCLSIDProgID 等等262728(2)COM庫(kù)庫(kù)COM構(gòu)件與客戶皆需要完成的相同操作構(gòu)件與客戶皆需要完成的相同操作由由OLE32.DL

17、L、OLE32.LIB實(shí)現(xiàn)實(shí)現(xiàn)COM庫(kù)中常用的函數(shù):庫(kù)中常用的函數(shù):初始化函數(shù)初始化函數(shù)與與GUID相關(guān)的函數(shù)相關(guān)的函數(shù)對(duì)象創(chuàng)建函數(shù)對(duì)象創(chuàng)建函數(shù)內(nèi)存管理函數(shù)內(nèi)存管理函數(shù)29 在使用在使用COM庫(kù)中的其他函數(shù)(除庫(kù)中的其他函數(shù)(除CoBuildVersion)之前,進(jìn)程必須先調(diào)用:之前,進(jìn)程必須先調(diào)用:HRESULT CoInitialize(void * reserved) 在退出之前調(diào)用:在退出之前調(diào)用:void CoUninitialize(void * reserved) 其他:其他:CoBuildVersionCoFreeUnusedLibraries OleInitialize建立在

18、建立在CoInitialize基礎(chǔ)之上基礎(chǔ)之上 DCOM使用使用CoInitializeEx初始化函數(shù):初始化函數(shù):30與與GUID(CLSID)相關(guān)的函數(shù):相關(guān)的函數(shù):例如:將例如:將GUID轉(zhuǎn)換為一個(gè)字符串:轉(zhuǎn)換為一個(gè)字符串:wchar_t szCLSID39;int r = : StringFromGUID2(CLSID_Component1, szCLSID, 39);其它:其它:StringFromCLSIDStringFromIIDCLSIDFromStringIIDFromStringIsEqualGUIDIsEqualIIDIsEqualCLSIDCLSIDFromProgID

19、31對(duì)象創(chuàng)建函數(shù):對(duì)象創(chuàng)建函數(shù):CoGetClassObjectCoCreateInstanceCoCreateInstanceExCoRegisterClassObjectCoRevokeClassObjectCoDisconnectObject內(nèi)存管理函數(shù):內(nèi)存管理函數(shù):CoTaskMemAllocCoTaskMemReallocCoTaskMemFreeCoGerMalloc32能夠創(chuàng)建其他構(gòu)件的構(gòu)件能夠創(chuàng)建其他構(gòu)件的構(gòu)件(構(gòu)件廠構(gòu)件廠)其本身也是一個(gè)其本身也是一個(gè)COM對(duì)象對(duì)象支持一個(gè)特殊的接口支持一個(gè)特殊的接口 IClassFacroty每一個(gè)每一個(gè)COM對(duì)象類應(yīng)該有一個(gè)相應(yīng)的類廠對(duì)

20、象對(duì)象類應(yīng)該有一個(gè)相應(yīng)的類廠對(duì)象33CoCreateInstanceCOM庫(kù)函數(shù)之一庫(kù)函數(shù)之一HRESULT_stdcall CoCreateInstance(const CLSID& clsid,Iunkown * pIUnknownOuter,DWORD dwClsContext,const IID& iid,void * ppv);clsid:待創(chuàng)建構(gòu)件的標(biāo)識(shí);待創(chuàng)建構(gòu)件的標(biāo)識(shí);pIUnknownOuter:用于聚合;:用于聚合;dwClsContext:限定所創(chuàng)建構(gòu)件的上下文;:限定所創(chuàng)建構(gòu)件的上下文;iid:構(gòu)件上待使用接口的標(biāo)識(shí);:構(gòu)件上待使用接口的標(biāo)識(shí);ppv:所返回接口的指針。

21、:所返回接口的指針。34一個(gè)使用例子:一個(gè)使用例子:IX * pIX = NULL;HRESULT he = :CoCreateInstance( CLSID_Component1,NULL,CLSCTX_INPROC_SERVER,IID_IDX,(void *) &pIX);if (SUCCEEDED(hr) pIX - FX();pIX - Release();35類廠類廠CoCreateInstance實(shí)際上實(shí)際上未直接創(chuàng)建未直接創(chuàng)建COM構(gòu)件構(gòu)件創(chuàng)建了一個(gè)被稱為類廠的構(gòu)件創(chuàng)建了一個(gè)被稱為類廠的構(gòu)件類廠構(gòu)件的唯一功能是創(chuàng)建其他構(gòu)件類廠構(gòu)件的唯一功能是創(chuàng)建其他構(gòu)件客戶可以通過(guò)類廠所支持的

22、接口來(lái)客戶可以通過(guò)類廠所支持的接口來(lái)對(duì)類廠創(chuàng)建對(duì)類廠創(chuàng)建構(gòu)件的過(guò)程加以控制構(gòu)件的過(guò)程加以控制CoCreateInstance調(diào)用調(diào)用CoGetClassObject創(chuàng)建構(gòu)件的標(biāo)準(zhǔn)接口是創(chuàng)建構(gòu)件的標(biāo)準(zhǔn)接口是IClassFactory36CoGetClassObject創(chuàng)建類廠創(chuàng)建類廠HRESULT_stdcall CoGetClassObject(const CLSID& clsid,DWORD dwClsContext,COSERVERINFO * pServerInfo,/用于用于DCOMconst IID& iid,void * ppv /指向類廠中某個(gè)接口的指針指向類廠中某個(gè)接口的指針)

23、;37IClassFactory 用于創(chuàng)建構(gòu)件的標(biāo)準(zhǔn)接口用于創(chuàng)建構(gòu)件的標(biāo)準(zhǔn)接口Interface IClassFactory: IUnknownHRESULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );HRESULT _stdcall LockServer(BOOL block);未接收未接收CLSID:只能創(chuàng)建同某個(gè):只能創(chuàng)建同某個(gè)CLSID相應(yīng)的構(gòu)件相應(yīng)的構(gòu)件IClassFactory238CoCreateInstance 與與 CoGetClassObject的關(guān)系:的關(guān)系:

24、CoCreateInstance 通過(guò)通過(guò) CoGetClassObject實(shí)現(xiàn)實(shí)現(xiàn)HRESULT CoCreateInstance(const CLSID& clsid,IUnknown * pUnknownDuter,DWOED dwClsContext,const IID& iid,void * ppv) * ppv = NULL;IClassFactory * pIFactory = NULL;HRESULT hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void)* &pIFactory);i

25、f (SUCCEEDED(hr)hr=pIFactory-CreateInstance(pUnknownOuter, iid, ppv);pIFactory - Release();return hr;39在下列情況下應(yīng)直接使用在下列情況下應(yīng)直接使用CoGetClassObject 而應(yīng)使用而應(yīng)使用CoCreateInstance:(1)如果希望用不同于如果希望用不同于IClassFactory的某個(gè)創(chuàng)建接口的某個(gè)創(chuàng)建接口來(lái)創(chuàng)建構(gòu)件來(lái)創(chuàng)建構(gòu)件 例如例如 IClassFactory2(2)如果希望創(chuàng)建同一構(gòu)件的多個(gè)實(shí)例如果希望創(chuàng)建同一構(gòu)件的多個(gè)實(shí)例40(4)類廠的實(shí)現(xiàn))類廠的實(shí)現(xiàn)CoGetCla

26、ssObject需要需要DLL中的一個(gè)特定的函數(shù)中的一個(gè)特定的函數(shù)來(lái)創(chuàng)建構(gòu)件的類廠來(lái)創(chuàng)建構(gòu)件的類廠DllGetClassObject:STDAPI DllGetClassObject(const CLSID& clsid,const IID& iid,void * ppv);41創(chuàng)建、調(diào)用構(gòu)件的過(guò)程:創(chuàng)建、調(diào)用構(gòu)件的過(guò)程:客戶客戶COM庫(kù)庫(kù)DLLCoGetClassObject調(diào)用調(diào)用CoGetClassObjectDllGetClassObjectIClassFactoryIXpIClassFactorypIX創(chuàng)建類廠創(chuàng)建類廠創(chuàng)建構(gòu)件創(chuàng)建構(gòu)件返回返回IClassFactory調(diào)用調(diào)用ICla

27、ssFactory:CreateInstance返回返回IX調(diào)用調(diào)用IX:Fx42#include #include #include Iface.hint main()CoInitialize(NULL) ;IX* pIX = NULL ; HRESULT hr = :CoCreateInstance(CLSID_Component1,NULL, CLSCTX_INPROC_SERVER, IID_IX, (void*)&pIX) ;if (SUCCEEDED(hr)pIX-Fx() ; / Use interface IX.IY* pIY = NULL ;hr = pIX-QueryInt

28、erface(IID_IY, (void*)&pIY) ;if (SUCCEEDED(hr)pIY-Fy() ; / Use interface IY.pIY-Release() ;客戶方代碼客戶方代碼(5)例子)例子43IZ* pIZ = NULL ;hr = pIX-QueryInterface(IID_IZ, (void*)&pIZ) ;if (SUCCEEDED(hr)pIZ-Fz() ;pIZ-Release() ;pIX-Release() ;elsecout Client: ttCould not create component. hr = hex hr endl ; / Un

29、initialize COM LibraryCoUninitialize() ;return 0 ;44#include #include #include Iface.h / Interface declarations#include Registry.h / Registry helper functionsstatic HMODULE g_hModule = NULL ; / DLL module handlestatic long g_cComponents = 0 ; / Count of active componentsstatic long g_cServerLocks =

30、0 ; / Count of locks/ Friendly name of componentconst char g_szFriendlyName = Inside COM, Ch 7 Example ;/ Version-independent ProgIDconst char g_szVerIndProgID = InsideCOM.Chap07 ;服務(wù)器方代碼服務(wù)器方代碼45class CA : public IX, public IY public:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, v

31、oid* ppv) ;virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/ Interface IXvirtual void _stdcall Fx() cout Fx endl ;/ Interface IYvirtual void _stdcall Fy() cout Fy endl ; / ConstructorCA() ;/ DestructorCA() ;private:/ Reference countlong m_cRef ; ;46HRESULT _stdcall CA:QueryInterfa

32、ce(const IID& iid, void* ppv)if (iid = IID_IUnknown)*ppv = static_cast(this) ; else if (iid = IID_IX)*ppv = static_cast(this) ;else if (iid = IID_IY)*ppv = static_cast(this) ; else*ppv = NULL ;return E_NOINTERFACE ;reinterpret_cast(*ppv)-AddRef() ;return S_OK ;47class CFactory : public IClassFactory

33、public:/ IUnknownvirtual HRESULT _stdcall QueryInterface(const IID& iid, void* ppv) ; virtual ULONG _stdcall AddRef() ;virtual ULONG _stdcall Release() ;/ Interface IClassFactoryvirtual HRESULT _stdcall CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) ;virtual HRESULT _stdcall Lock

34、Server(BOOL bLock) ; / ConstructorCFactory() : m_cRef(1) / DestructorCFactory() private:long m_cRef ; ;48HRESULT _stdcall CFactory:QueryInterface(const IID& iid, void* ppv)if (iid = IID_IUnknown) | (iid = IID_IClassFactory)*ppv = static_cast(this) ; else *ppv = NULL ;return E_NOINTERFACE ;reinterpre

35、t_cast(*ppv)-AddRef() ;return S_OK ;ULONG _stdcall CFactory:AddRef()return InterlockedIncrement(&m_cRef) ;ULONG _stdcall CFactory:Release() if (InterlockedDecrement(&m_cRef) = 0)delete this ;return 0 ;return m_cRef ;49/ IClassFactory implementationHRESULT _stdcall CFactory:CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void* ppv) if (pUnknownOuter != NULL)return CLASS_E_NOAGGREGATION ;CA* pA = new CA ;if (pA = NULL)return E_OUTOFMEMORY ;HRESULT hr = pA-QueryInterface(iid, ppv) ;/ Rele

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論