您的位置:首页 > 其它

通过ATL实现类厂和组件的创建

2013-09-27 10:05 309 查看
类工厂的实现,组件的创建过程

1. 在*_Server.cpp 中有

[cpp]
view plaincopyprint?

BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_Math, CMath) END_OBJECT_MAP()

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_Math, CMath)
END_OBJECT_MAP()


展开后是这样:

[cpp]
view plaincopyprint?

struct _ATL_OBJMAP_ENTRY30 { const CLSID* pclsid; HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister); _ATL_CREATORFUNC* pfnGetClassObject; _ATL_CREATORFUNC* pfnCreateInstance; IUnknown* pCF; DWORD dwRegister; _ATL_DESCRIPTIONFUNC* pfnGetObjectDescription; _ATL_CATMAPFUNC* pfnGetCategoryMap; void (WINAPI *pfnObjectMain)(bool bStarting); }; static ATL::_ATL_OBJMAP_ENTRY ObjectMap[] = { { &CLSID_Math, CMath::UpdateRegistry, CMath::_ClassFactoryCreatorClass::CreateInstance, CMath::_CreatorClass::CreateInstance, NULL, 0, CMath::GetObjectDescription, CMath::GetCategoryMap, CMath::ObjectMain }, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} };

struct _ATL_OBJMAP_ENTRY30
{
const CLSID* pclsid;
HRESULT (WINAPI *pfnUpdateRegistry)(BOOL bRegister);
_ATL_CREATORFUNC* pfnGetClassObject;
_ATL_CREATORFUNC* pfnCreateInstance;
IUnknown* pCF;
DWORD dwRegister;
_ATL_DESCRIPTIONFUNC* pfnGetObjectDescription;
_ATL_CATMAPFUNC* pfnGetCategoryMap;
void (WINAPI *pfnObjectMain)(bool bStarting);
};
static ATL::_ATL_OBJMAP_ENTRY ObjectMap[] =
{
{
&CLSID_Math,
CMath::UpdateRegistry,
CMath::_ClassFactoryCreatorClass::CreateInstance,
CMath::_CreatorClass::CreateInstance,
NULL,
0,
CMath::GetObjectDescription,
CMath::GetCategoryMap,
CMath::ObjectMain
},
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};


定义了一个_ATL_OBJMAP_ENTRY 类型的全局数组变量 ObjectMap

然后在 Dll 被载入时用这个数组初始化全局的 _Module 变量

[cpp]
view plaincopyprint?

CComModule _Module;
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{//......
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance);
}
}
inline HRESULT CComModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE /*h*/, const GUID* plibid) throw()
{//......
m_pObjMap = p;
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
pEntry->pfnObjectMain(true); //这里就是 CMath::ObjectMain
pEntry++;
}
}

CComModule _Module;
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{//......
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance);
}
}
inline HRESULT CComModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE /*h*/, const GUID* plibid) throw()
{//......
m_pObjMap = p;
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
pEntry->pfnObjectMain(true); //这里就是 CMath::ObjectMain
pEntry++;
}
}


当用户代码中调用 CoCreateInstance 时

HRESULT hr = CoCreateInstance( CLSID_Math,

NULL,

CLSCTX_INPROC,

IID_IMath,

(void**) &pMath );

Dll 中的 DllGetClassObject 会被调用,最终调用 CMath::_ClassFactoryCreatorClass::CreateInstance 创建CMath组件

[cpp]
view plaincopyprint?

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
inline HRESULT CComModule::GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
{
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
{
//pEntry->pfnGetClassObject == CMath::_ClassFactoryCreatorClass::CreateInstance
//pEntry->pfnCreateInstance == CMath::_CreatorClass::CreateInstance
pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
pEntry->pCF->QueryInterface(riid, ppv);
break;
}
pEntry++;
}
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
inline HRESULT CComModule::GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
{
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
{
//pEntry->pfnGetClassObject == CMath::_ClassFactoryCreatorClass::CreateInstance
//pEntry->pfnCreateInstance == CMath::_CreatorClass::CreateInstance
pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
pEntry->pCF->QueryInterface(riid, ppv);
break;
}
pEntry++;
}
}


接下来看 CComCoClass 又是如何帮助实现 CMath::_ClassFactoryCreatorClass::CreateInstance 创建类厂的

[cpp]
view plaincopyprint?

class ATL_NO_VTABLE CMath : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CMath, &CLSID_Math>, //...... { } template <class T, const CLSID* pclsid = &CLSID_NULL> //T = CMath, pclsid = CLSID_Math class CComCoClass { public: //DECLARE_CLASSFACTORY() //DECLARE_AGGREGATABLE(T) typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass; typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass; typedef T _CoClass; template <class Q> static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp) { return T::_CreatorClass::CreateInstance(punkOuter, __uuidof(Q), (void**) pp); } };

class ATL_NO_VTABLE CMath :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMath, &CLSID_Math>,
//......
{
}
template <class T, const CLSID* pclsid = &CLSID_NULL> //T = CMath, pclsid = CLSID_Math
class CComCoClass
{
public:
//DECLARE_CLASSFACTORY()
//DECLARE_AGGREGATABLE(T)
typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass;
typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass;
typedef T _CoClass;
template <class Q>
static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp)
{
return T::_CreatorClass::CreateInstance(punkOuter, __uuidof(Q), (void**) pp);
}
};


可见在 CComCoClass 中有两个typedef的定义,

_ClassFactoryCreatorClass 用于创建类厂

而 _CreatorClass用于创建组件实例

DllGetClassObject 最终调用了其中的 _ClassFactoryCreatorClass 的 CreateInstance函数创建类厂

将 _ClassFactoryCreatorClass 展开

[cpp]
view plaincopyprint?

//typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass; template <class T1> //T1 = ATL::CComObjectCached< ATL::CComClassFactory > 类厂 //T1 = ATL::CComCreator< ATL::CComObject< CMath > >, ATL::CComCreator< ATL::CComAggObject< CMath > > 组件 class CComCreator { public: static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) { *ppv = NULL; HRESULT hRes = E_OUTOFMEMORY; T1* p = new T1(pv)); //这里创建了组件或类厂 if (p != NULL) { p->SetVoid(pv); //pv = CMath::_CreatorClass::CreateInstance p->InternalFinalConstructAddRef(); hRes = p->_AtlInitialConstruct(); if (SUCCEEDED(hRes)) hRes = p->FinalConstruct(); if (SUCCEEDED(hRes)) hRes = p->_AtlFinalConstruct(); p->InternalFinalConstructRelease(); if (hRes == S_OK) hRes = p->QueryInterface(riid, ppv); //获取组件接口指针 if (hRes != S_OK) delete p; } return hRes; } };

//typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass;
template <class T1> //T1 = ATL::CComObjectCached< ATL::CComClassFactory > 类厂
//T1 = ATL::CComCreator< ATL::CComObject< CMath > >, ATL::CComCreator< ATL::CComAggObject< CMath > > 组件
class CComCreator
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
T1* p =  new T1(pv)); //这里创建了组件或类厂
if (p != NULL)
{
p->SetVoid(pv); //pv = CMath::_CreatorClass::CreateInstance
p->InternalFinalConstructAddRef();
hRes = p->_AtlInitialConstruct();
if (SUCCEEDED(hRes))
hRes = p->FinalConstruct();
if (SUCCEEDED(hRes))
hRes = p->_AtlFinalConstruct();
p->InternalFinalConstructRelease();
if (hRes == S_OK)
hRes = p->QueryInterface(riid, ppv); //获取组件接口指针
if (hRes != S_OK)
delete p;
}
return hRes;
}
};


DllGetClassObject 调用

[cpp]
view plaincopyprint?

//pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF); CMath::_ClassFactoryCreatorClass::CreateInstance (CMath::_CreatorClass::CreateInstance, __uuidof(IUnknown), (LPVOID*)NULL);

//pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
CMath::_ClassFactoryCreatorClass::CreateInstance (CMath::_CreatorClass::CreateInstance, __uuidof(IUnknown), (LPVOID*)NULL);


然后在这里面创建了类厂 :ATL::CComObjectCached< ATL::CComClassFactory >* p = new ATL::CComObjectCached< ATL::CComClassFactory >(pv));

最终获得类厂的接口 :p->QueryInterface(riid, ppv);

类厂类是ATL::CComClassFactory 它的定义

[cpp]
view plaincopyprint?

typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv); class CComClassFactory : public IClassFactory, public CComObjectRootEx<CComGlobalsThreadModel> { public: BEGIN_COM_MAP(CComClassFactory) COM_INTERFACE_ENTRY(IClassFactory) END_COM_MAP() STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj) { HRESULT hRes = E_POINTER; *ppvObj = NULL; if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid)) //检查参数 { ATLTRACE(atlTraceCOM, 0, _T("CComClassFactory: asked for non IUnknown interface while creating an aggregated object")); hRes = CLASS_E_NOAGGREGATION; } else hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); return hRes; } void SetVoid(void* pv) //pv = CMath::_CreatorClass::CreateInstance { m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv; } _ATL_CREATORFUNC* m_pfnCreateInstance; };

typedef HRESULT (WINAPI _ATL_CREATORFUNC)(void* pv, REFIID riid, LPVOID* ppv);
class CComClassFactory :
public IClassFactory,
public CComObjectRootEx<CComGlobalsThreadModel>
{
public:
BEGIN_COM_MAP(CComClassFactory)
COM_INTERFACE_ENTRY(IClassFactory)
END_COM_MAP()

STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
HRESULT hRes = E_POINTER;
*ppvObj = NULL;
if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid)) //检查参数
{
ATLTRACE(atlTraceCOM, 0, _T("CComClassFactory: asked for non IUnknown interface while creating an aggregated object"));
hRes = CLASS_E_NOAGGREGATION;
}
else
hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj);
return hRes;
}
void SetVoid(void* pv) //pv = CMath::_CreatorClass::CreateInstance
{
m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;
}
_ATL_CREATORFUNC* m_pfnCreateInstance;
};


这里面有趣的是 SetVoid(void* pv) 它将 CMath::_CreatorClass::CreateInstance 传给了类厂指针成员变量 _ATL_CREATORFUNC* m_pfnCreateInstance

然后,在调用类厂 CreateInstance 创建对象实例时, 它会在检查参数后,调用 CMath::_CreatorClass::CreateInstance

那再看看 CMath::_CreatorClass::CreateInstance 会是如何实现创建组件实例

[cpp]
view plaincopyprint?

typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass; template <class T1, class T2> //T1 = ATL::CComCreator< ATL::CComObject< CMath > >, T2 = ATL::CComCreator< ATL::CComAggObject< CMath > > class CComCreator2 { public: static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) { ATLASSERT(ppv != NULL); return (pv == NULL) ? ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv) : ATL::CComCreator< ATL::CComAggObject< CMath > >::CreateInstance(pv, riid, ppv); } };

typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< x > >, ATL::CComCreator< ATL::CComAggObject< x > > > _CreatorClass;
template <class T1, class T2> //T1 = ATL::CComCreator< ATL::CComObject< CMath > >, T2 = ATL::CComCreator< ATL::CComAggObject< CMath > >
class CComCreator2
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
ATLASSERT(ppv != NULL);
return (pv == NULL) ?
ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv) :
ATL::CComCreator< ATL::CComAggObject< CMath > >::CreateInstance(pv, riid, ppv);
}
};


它会通过pv参数判断组件是否组合,然后选择相应的创建模板类

-------------------------------------------------------------------------------------------------------------

总结一下类厂和组件的创建过程

类厂创建过程:

1. 在*_Server.cpp 中定义CComModule _Module 全局变量和一个数组,里面填入组件创建的相关函数信息

[cpp]
view plaincopyprint?

CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_Math, CMath) END_OBJECT_MAP()

CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_Math, CMath) END_OBJECT_MAP()


2. Dll 加载时完成_Module的初始化

[cpp]
view plaincopyprint?

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID ) { if (dwReason == DLL_PROCESS_ATTACH) { _Module.Init(ObjectMap, hInstance); } } inline HRESULT CComModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE , const GUID* plibid) throw() { m_pObjMap = p; //...... }

BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID )
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance);
}
}
inline HRESULT CComModule::Init(_ATL_OBJMAP_ENTRY* p, HINSTANCE , const GUID* plibid) throw()
{
m_pObjMap = p;
//......
}


3. 用户调用 CoCreateInstance 时,dll导出函数 DllGetClassObject 会被调用

[cpp]
view plaincopyprint?

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
//rclsid = CLSID_Math
inline HRESULT CComModule::GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
{//......
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
{
//pEntry->pfnGetClassObject == CMath::_ClassFactoryCreatorClass::CreateInstance
//pEntry->pfnCreateInstance == CMath::_CreatorClass::CreateInstance
hr = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
break;
}
pEntry++;
}
}

STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
//rclsid = CLSID_Math
inline HRESULT CComModule::GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) throw()
{//......
_ATL_OBJMAP_ENTRY* pEntry = m_pObjMap;
while (pEntry->pclsid != NULL)
{
if ((pEntry->pfnGetClassObject != NULL) && InlineIsEqualGUID(rclsid, *pEntry->pclsid))
{
//pEntry->pfnGetClassObject == CMath::_ClassFactoryCreatorClass::CreateInstance
//pEntry->pfnCreateInstance == CMath::_CreatorClass::CreateInstance
hr = pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, __uuidof(IUnknown), (LPVOID*)&pEntry->pCF);
break;
}
pEntry++;
}
}


4. DllGetClassObject 会导致 CMath::_ClassFactoryCreatorClass::CreateInstance 的调用

[cpp]
view plaincopyprint?

CMath::_ClassFactoryCreatorClass 类型是 CComCreator, 也就是 CComCreator::CreateInstance 被调用,创建了类厂 //typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass; template <class T1> //T1 = ATL::CComObjectCached< ATL::CComClassFactory > 类厂 class CComCreator {//...... static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) { *ppv = NULL; HRESULT hRes = E_OUTOFMEMORY; T1* p = new T1(pv)); //这里创建了类厂 if (p != NULL) { p->SetVoid(pv); //pv = CMath::_CreatorClass::CreateInstance p->QueryInterface(riid, ppv); //获取组件接口指针 //...... } } };

CMath::_ClassFactoryCreatorClass 类型是 CComCreator, 也就是 CComCreator::CreateInstance 被调用,创建了类厂
//typedef ATL::CComCreator< ATL::CComObjectCached< ATL::CComClassFactory > > _ClassFactoryCreatorClass;
template <class T1> //T1 = ATL::CComObjectCached< ATL::CComClassFactory > 类厂
class CComCreator
{//......
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
T1* p =  new T1(pv)); //这里创建了类厂
if (p != NULL)
{
p->SetVoid(pv); //pv = CMath::_CreatorClass::CreateInstance
p->QueryInterface(riid, ppv); //获取组件接口指针
//......
}
}
};


*********************************************************************************

组件的创建过程:

1. CComCreator::CreateInstance 创建类厂后,会调用 SetVoid(pv) 将组件创建的函数指针创给了类工厂

[cpp]
view plaincopyprint?

class CComClassFactory : //..... {//..... void SetVoid(void* pv) //pv = CMath::_CreatorClass::CreateInstance { m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv; } _ATL_CREATORFUNC* m_pfnCreateInstance; };

class CComClassFactory : //.....
{//.....
void SetVoid(void* pv) //pv = CMath::_CreatorClass::CreateInstance
{
m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv;
}
_ATL_CREATORFUNC* m_pfnCreateInstance;
};


2. 用户调用的 CoCreateInstance, 在成功创建类厂后,会调用类厂的 CreateInstance接口

[cpp]
view plaincopyprint?

class CComClassFactory : //..... {//..... STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj) { HRESULT hRes = E_POINTER; *ppvObj = NULL; if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid)) //检查参数 { ATLTRACE(atlTraceCOM, 0, _T("CComClassFactory: asked for non IUnknown interface while creating an aggregated object")); hRes = CLASS_E_NOAGGREGATION; } else hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); //调用组件创建函数 return hRes; } _ATL_CREATORFUNC* m_pfnCreateInstance; //m_pfnCreateInstance = CMath::_CreatorClass::CreateInstance };

class CComClassFactory : //.....
{//.....
STDMETHOD(CreateInstance)(LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj)
{
HRESULT hRes = E_POINTER;
*ppvObj = NULL;
if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid)) //检查参数
{
ATLTRACE(atlTraceCOM, 0, _T("CComClassFactory: asked for non IUnknown interface while creating an aggregated object"));
hRes = CLASS_E_NOAGGREGATION;
}
else
hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); //调用组件创建函数
return hRes;
}
_ATL_CREATORFUNC* m_pfnCreateInstance; //m_pfnCreateInstance = CMath::_CreatorClass::CreateInstance
};


3. 类厂的 CreateInstance 会调用通过 SetVoid 获取的组件创建的函数指针, 也就是CMath::_CreatorClass::CreateInstance

[cpp]
view plaincopyprint?

//typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< CMath > >, ATL::CComCreator< ATL::CComAggObject< CMath > > > _CreatorClass; template <class T1, class T2> //T1 = ATL::CComCreator< ATL::CComObject< CMath > >, T2 = ATL::CComCreator< ATL::CComAggObject< CMath > > class CComCreator2 { public: static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) { ATLASSERT(ppv != NULL); return (pv == NULL) ? ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv) : ATL::CComCreator< ATL::CComAggObject< CMath > >::CreateInstance(pv, riid, ppv); } };

//typedef ATL::CComCreator2< ATL::CComCreator< ATL::CComObject< CMath > >, ATL::CComCreator< ATL::CComAggObject< CMath > > > _CreatorClass;
template <class T1, class T2> //T1 = ATL::CComCreator< ATL::CComObject< CMath > >, T2 = ATL::CComCreator< ATL::CComAggObject< CMath > >
class CComCreator2
{
public:
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
ATLASSERT(ppv != NULL);
return (pv == NULL) ?
ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv) :
ATL::CComCreator< ATL::CComAggObject< CMath > >::CreateInstance(pv, riid, ppv);
}
};


4. CComCreator2 会通过检查pv参数,确定是创建组合对象还是非组合对象,最终还是通过 CComCreator 创建组件

[cpp]
view plaincopyprint?

//ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv); template <class T1> //T1 = ATL::CComCreator< ATL::CComObject< CMath > > 或 ATL::CComCreator< ATL::CComAggObject< CMath > > 创建组件 class CComCreator {//..... static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) { *ppv = NULL; HRESULT hRes = E_OUTOFMEMORY; //ATL::CComObject< CMath > *p = new ATL::CComObject< CMath > (pv); T1* p = new T1(pv)); //这里创建了组件或类厂 //..... hRes = p->QueryInterface(riid, ppv); //获取组件接口指针 return hRes; } };

//ATL::CComCreator< ATL::CComObject< CMath > >::CreateInstance(NULL, riid, ppv);
template <class T1> //T1 = ATL::CComCreator< ATL::CComObject< CMath > > 或 ATL::CComCreator< ATL::CComAggObject< CMath > > 创建组件
class CComCreator
{//.....
static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
HRESULT hRes = E_OUTOFMEMORY;
//ATL::CComObject< CMath > *p = new ATL::CComObject< CMath > (pv);
T1* p =  new T1(pv)); //这里创建了组件或类厂
//.....
hRes = p->QueryInterface(riid, ppv); //获取组件接口指针
return hRes;
}
};


到此,组件创建完成。

/article/9948068.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: