類廠IClassFactory和組件的創建

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相應的類廠是由實現組件的開發人員實現的。
DllGetClassObject
CoGetClassObject需要DLL中一個名爲DllGetClassObject的函數來完成類廠的創建。此函數定義如下:
STDAPI DllGetClassObject(
        Const CLSID& clsid,
        Const IID& iid,
        Void** ppv
        );
DllGetClassObject是的我們可以在同一個DLL中實現多個組件。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章