第七步 實現IClassFactory的方法<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
實現類CAddFactory的方法。創建一個新文件(AddObjFactory.cpp)。提供類IUnknown和IClassFactory的方法實現。AddRef,Release和QueryInterface方法實現和前面類CAddObj中這三個函數實現基本一樣。在方法CreateInstance中,類CaddObj被實例化並且傳回其接口指針。LockServer方法沒有給出細節的實現。
HRESULT __stdcall CAddFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
//
//This method lets the client manufacture components en masse
//The class factory provides a mechanism to control the way
//the component is created. Within the class factory the
//author of the component may decide to selectivey enable
//or disable creation as per license agreements
//
//
// Cannot aggregate.
if (pUnknownOuter != NULL)
{
return CLASS_E_NOAGGREGATION ;
}
//
// Create an instance of the component.
//
CAddObj* pObject = new CAddObj ;
if (pObject == NULL)
{
return E_OUTOFMEMORY ;
}
//
// Get the requested interface.
//
return pObject->QueryInterface(iid, ppv) ;
}
HRESULT __stdcall CAddFactory::LockServer(BOOL bLock)
{
return E_NOTIMPL;
}
/////////////////////////////////////////////////////////////////
第八步 實現DllGetClassObject的方法
一個進程內COM對象只是一個簡單的WIN32DLL,他遵循既定的協議。每一個COM DLL必須有一個通過名字DllGetClassObject的出口函數。客戶端將調用這個函數以得到類廠的接口(IUnknown or IClassFactory),之後就是調用CreateInstance方法。創建一個新文件(Exports.cpp),在其中實現DllGetClassObject。(代碼如下)
STDAPI DllGetClassObject(const CLSID& clsid,
const IID& iid,
void** ppv)
{
//
//Check if the requested COM object is implemented in this DLL
//There can be more than 1 COM object implemented in a DLL
//
if (clsid == CLSID_AddObject)
{
//
//iid specifies the requested interface for the factory object
//The client can request for IUnknown, IClassFactory,
//IClassFactory2
//
CAddFactory *pAddFact = new CAddFactory;
if (pAddFact == NULL)
return E_OUTOFMEMORY;
else
{
return pAddFact->QueryInterface(iid , ppv);
}
}
//
//if control reaches here then that implies that the object
//specified by the user is not implemented in this DLL
//
return CLASS_E_CLASSNOTAVAILABLE;
}
/////////////////////////////////////////////////////////////////
第九步 實現DllCanUnloadNow
客戶需要知道什麼時候COM DLL可以被從內存中卸載。更進一步,一個進程內COM對象顯示的通過調用API函數LoadLibrary裝入內存中的客戶程序的進程空間中。這個顯示裝載的DLL也可以使用FreeLibrary卸載。COM客戶必須知道什麼時候DLL可以被安全的卸載。一個客戶必須確定沒有任何來自於特別是DLL中的COM對象的實例仍在生命期中。要使得這個可以被簡單的計算,在一個COM DLL中,我們在類CAddObj和CAddFactory的構造函數中自加一個全局變量(g_nComObjsInUse)。類似的,在析構函數中,自減這個全局變量。
我們輸出另一個COM規定的函數:DllCanUnloadedNow,實現如下:
STDAPI DllCanUnloadNow()
{
//
//A DLL is no longer in use when it is not managing any existing objects
// (the reference count on all of its objects is 0).
//We will examine the value of g_nComObjsInUse
//
if (g_nComObjsInUse == 0)
{
return S_OK;
}
else
{
return S_FALSE; }
}
COM指南 (Step by Step COM Tutorial)-上 COM指南 (Step by Step COM Tutorial)-中 COM指南 (Step by Step COM Tutorial)-下(2)