CoCreateInstance是建立組件時使用得最多的一種方法,但由於其靈活性不足以滿足所有組件的需求,因此引入了類廠。所有的組件都是類廠建立的。CoCreateInstance實際上也是按照一般發方法通過類廠來建立組件的。當客戶直接使用類廠時,將能夠獲得更高的靈活性。
1. CoCreateInstance函數
此函數需要一個CLSID參數來建立相應組件的一個執行個體,並返回此執行個體的某個介面。
HRESULT
__stdcall CoCreateInstance( const CLSID clsid, IUnkown* pIUnkownOuter,//outer component DWORD dwClsContext, //server context const IID& iid, void** ppv );這裡,函數的第三個參數dwClsContext可以控制所建立的組件是在與客戶相同的進程中運行,還是在不同的進程中運行,或者是在另外一台機器上運行。此參數的值可以是如下所列各值的組合。
CLSCTX_INPROC_SERVER 客戶希望建立在同一進程中啟動並執行組件。為實現這一點,組件必須是在DLL中實現的。
CLSCTX_INPROC_HANDLER 客戶希望建立進程中處理器。進程中處理器實際上是一個只實現了某個組件一部分的進程中組件,該組件的其他部分將由本地或遠程伺服器上的某個進程外組件實現。
CLSCTX_LOCAL_SERVER
客戶希望建立一個在同一機器上的另外一個進程中啟動並執行組件。本機伺服器是由exe實現的。
CLSCTX_REMOTE_SERVER
客戶希望建立一個在遠程機器上啟動並執行組件。此標誌需要分布式COM正常工作。
CoCreateInstance的不靈活性在於,它沒有給客戶提供一種能夠控制組件建立過程的方法,當CoCreateInstance完成之後,組件實際上已經建立起來了,之後要想控制將組件裝載到記憶體中何處或檢查客戶是否有許可權來建立該組件基本上已經是不可能的了。在組件建立好之後,可以通過一個介面來初始化它,但在建立之前卻無法獲得它的介面,也就無法對組件的建立加上條件限制。為解決組件的建立過程的控制問題,引入了另外一個專門用於建立所需組件的組件——類廠。
2.
類廠建立其他組件是類廠的唯一功能,而且某個特定的類廠將建立只同某個特定的CLSID相應的組件,而客戶則可以通過類廠所支援的介面來對類廠建立組件的過程加以控制。建立組件的標準介面是IClassFactory。
CoGetClassObject函數此函數和CoCreateInstance函數一樣,需要一個CLSID作為參數並返回相應類廠中某個介面指標的函數。其聲明如下:HRESULT __stdcall CoGetClassObject( const CLSID& clsid, DWORD dwClsContext, COSERVERINFO* pServerInfo,//reserved for DCOM const IID& iid, void** ppv );CoGetClassObject和CoCreateInstance的最大區別在於前者返回的是指向所需組件的類廠指標,而後者是指向所需組件的指標。客戶可以用前者所返回的指標來建立所需的組件,這個指標通常是一個IClassFactory指標。
IClassFactory介面其聲明如下:interface IClassFactory:IUnknown{ HRESULT __stdcall CreateInstance(IUnknown* pUnkownOuter, const IID& iid, void** ppv); HRESULT __stdcall LockServer(BOOL bLock);};除了IClassFactory之外,Microsoft還定義了另外一個建立介面IClassFactory2。此介面在IClasFactory的基礎上增加了許可或許可權功能。此時,客戶必須給類廠提供正確的關鍵字或許可以建立所需的組件。
什麼時候用CoGetClassObject?若想用不同於IClassFactory的某個建立介面來建立組件,則必須用CoGetClassObject。因此,如果想用IClassFactory2來建立組件,就應使用CoGetClassObject;若需建立同一組件的多個執行個體,使用CoGetClassFactory可獲得更高的效力。因為這樣只要建立相應的類廠一次,而CoCreateInstance需為每一個執行個體分別建立並釋放相應的類廠。另外CoGetClassFactory使客戶可對組件的建立過程進行更多的控制。
類廠的兩個特性首先,類廠的一個執行個體只能建立同某個CLSID相應的組件。體現在CoGetClassObject借接收一個CLSID,而IClassFactory::CreateInstance卻不接收此參數。其次,在大多數情況下,類廠組件與它所建立的組件包含在相同的DLL中。與某個特定CLSID相應的類廠是由實現組件的開發人員實現的。
DllGetClassObjectCoGetClassObject需要DLL中一個名為DllGetClassObject的函數來完成類廠的建立。此函數定義如下:STDAPI DllGetClassObject( Const CLSID& clsid, Const IID& iid, Void** ppv );DllGetClassObject是的我們可以在同一個DLL中實現多個組件。