对于ATL生成的组件,很容易实现多个接口(不管是通过继承多个接口的方法或是通过内部类的方法),那么如何实现呢,关键还是对于组件的生存周期管理和创建管理,另外就是组件对于多接口查询的支持了。
对于多重继承和内部类实现多重接口组件的模拟类图如下:
源代码如下
#include "stdafx.h"
#include "wtypes.h"
#include "objbase.h"
#include "initguid.h"
// {84296355-694E-4869-84A9-CAE4E91F96F1}
DEFINE_GUID(IID_IX,
0x84296355, 0x694e, 0x4869, 0x84, 0xa9, 0xca, 0xe4, 0xe9, 0x1f, 0x96, 0xf1);
// {08C05339-AE03-4255-9A1A-0FDB05B7A289}
DEFINE_GUID(IID_IY,
0x8c05339, 0xae03, 0x4255, 0x9a, 0x1a, 0xf, 0xdb, 0x5, 0xb7, 0xa2, 0x89);
// {AC1164FA-9496-4003-88FB-10CF6160888E}
DEFINE_GUID(IID_IDeal,
0xac1164fa, 0x9496, 0x4003, 0x88, 0xfb, 0x10, 0xcf, 0x61, 0x60, 0x88, 0x8e);
// {6A854410-F80C-4e05-A42F-EF9031448E2A}
DEFINE_GUID(IID_YDeal,
0x6a854410, 0xf80c, 0x4e05, 0xa4, 0x2f, 0xef, 0x90, 0x31, 0x44, 0x8e, 0x2a);
//下面是模板部分代码
inline BOOL CEqualGUID(IID * rguid1, IID * rguid2)
{
return (
((PLONG) &rguid1)[0] == ((PLONG) &rguid2)[0] &&
((PLONG) &rguid1)[1] == ((PLONG) &rguid2)[1] &&
((PLONG) &rguid1)[2] == ((PLONG) &rguid2)[2] &&
((PLONG) &rguid1)[3] == ((PLONG) &rguid2)[3]);
}
//##ModelId=474BBB28029F
template <class T>
class CXX
{
//##ModelId=474BBB2802A1
T *p;
public:
//##ModelId=474BBB2802AF
CXX()
{
p = NULL;
}
//##ModelId=474BBB2802B0
CXX(T *ppv)
{
p = ppv;
p->AddRef();
}
//##ModelId=474BBB2802BF
~CXX(){
if(p)
p->Release();
}
//##ModelId=474BBB2802C0
T *operator ->(void){
if(p)
return p;
else
return NULL;
}
};
//模板类结束
//
//##ModelId=474BBB2802CE
class IU
{
public:
//##ModelId=474BBB2802CF
virtual ULONG AddRef() =0;
//##ModelId=474BBB2802DF
virtual ULONG Release() =0;
//##ModelId=474BBB2802E1
virtual ULONG QueryInterface(IID * iid, void **pThis)=0;
};
//
//模板多重继承类
//创建类
//##ModelId=474BBB2802FD
template<class Base>
class CoObject : public Base
{
//##ModelId=474BBB28030D
ULONG m_cbRef;
public:
//##ModelId=474BBB28030E
virtual ULONG AddRef()
{
m_cbRef ++;
return m_cbRef;
}
//##ModelId=474BBB280310
virtual ULONG Release()
{
m_cbRef --;
if(m_cbRef == 0)
delete this;
return m_cbRef;
}
//##ModelId=474BBB28031C
virtual ULONG QueryInterface(IID * iid, void **ppVoid)
{
CC_MAP *pentry = GetEntry();
int dd;
IID * guid;
IU * p = NULL;
while(pentry->iid != NULL)
{
// guid = pentry->iid;
if(memcmp((void *)pentry->iid, (void *)iid, sizeof(GUID)) == 0)
// if(CEqualGUID((IID *)pentry->iid, iid) )
// if(pentry->iid == iid)
{
p = (IU *) ((int)this + pentry->m_dwoffset);
p->AddRef();
break;
}
pentry ++;
}
if(p)
*ppVoid = p;
return 0;
}
//##ModelId=474BBB280320
CoObject()
{
m_cbRef = 0;
}
// static ULONG CreateInstance(REFIID riid, void **ppVoid)
// {
// *ppVoid = new Base();
// return 0;
// }
};
//##ModelId=474BBB28032C
template <class Base>
class CoXCreate
{
public:
//##ModelId=474BBB28033D
static ULONG CreateInstance(IID * iid, void **ppVoid)
{
Base *p= new Base();
/* p->AddRef();*/
p->QueryInterface(iid, ppVoid);
// if(iid == IID_IDEAL)
// *ppVoid = p;
// else if(iid == IID_IYDEAL)
// *ppVoid = p;
return 0;
}
};
//##ModelId=474BBB28034B
struct CC_MAP
{
//##ModelId=474BBB28035C
const IID * iid;
//##ModelId=474BBB280360
DWORD m_dwoffset;
};
#define DECLARE_CC_XX(x) public:/
typedef CoXCreate< CoObject <x> > Xobj;
#define catchiid(x) IID_##x
#define catchclass(x) m_p##x
#define offsetof(base, x ) ((DWORD)(static_cast<base*>((x*)8))-8)
#define offsetofin(s, m) (size_t)&(((s *)0)->m)
#define BEGIN_CC_INTER()/
public:/
virtual ULONG AddRef() = 0;/
virtual ULONG Release() = 0;/
virtual ULONG QueryInterface(IID * iid, void **ppVoid) = 0;
#define BEGIN_DD_INTER(x)/
typedef x _CCClass;/
public:/
CC_MAP * GetEntry(){/
static struct CC_MAP entry[] = {
#define END_DD_INTER() /
{NULL, 0}}; return entry; }
#define DD_INTER(xx)/
{ &catchiid(xx), offsetof(xx, _CCClass)},
#define DDI_INTER(xx, yy)/
{ &catchiid(xx), offsetofin(_CCClass, catchclass(yy))},
#define METHOD_EE(x) virtual ULONG x
#define BEGIN_EE_INTER(x, base) /
public :/
class x :public base/
{/
METHOD_EE(AddRef());/
METHOD_EE(Release());/
METHOD_EE(QueryInterface(IID * , void **));
#define END_EE_INTER(x) };/
x catchclass(x);
//##ModelId=474BBB28036B
template<class TBase>
class Create
{
public:
//##ModelId=474BBB280399
typedef TBase _TClass;
//##ModelId=474BBB28037B
static ULONG CreateInstance(IID * iid, void ** ppVoid)
{
/* _TClass *p;*/
// p = new _TClass();
// *ppVoid = p;
// p->AddRef();
TBase::Xobj::CreateInstance(iid, ppVoid);
// p = (_TClass *)(*ppVoid);
// p->AddRef();
return 0;
}
};
//##ModelId=474BBB2803A9
class IDeal : public IU
{
public:
//##ModelId=474BBB2803AB
virtual ULONG H1() = 0;
};
//##ModelId=474BBB2803B9
class YDeal : public IU
{
public:
//##ModelId=474BBB2803C9
virtual ULONG HH() = 0;
};
//##ModelId=474BBB2803D8
class CXDeal : /*public RefCount, */
public Create<CXDeal>,
public IDeal
{
public:
//##ModelId=474BBB2900EC
CXDeal(){}
//##ModelId=474BBB2900ED
virtual ULONG H1()
{
printf("Hello");
return 0;
}
DECLARE_CC_XX(CXDeal);
//##ModelId=474BBB2900EF
BEGIN_CC_INTER();
BEGIN_DD_INTER(CXDeal)
DD_INTER(IDeal)
END_DD_INTER()
};
//##ModelId=474BBB2900FA
class CYDeal : /*public RefCount,*/
public Create<CYDeal>,
public YDeal
{
public:
//##ModelId=474BBB29011B
CYDeal(){}
//##ModelId=474BBB29011C
virtual ULONG HH(){
printf("Hello");
return 0;
}
DECLARE_CC_XX(CYDeal);
//##ModelId=474BBB29011E
BEGIN_CC_INTER();
BEGIN_DD_INTER(CYDeal)
DD_INTER(YDeal)
END_DD_INTER()
};
//多重继承支持
//##ModelId=474BBB290128
class CXYDeal : /*public RefCount,*/
public Create<CXYDeal>,
public YDeal,
public IDeal
{
public:
//##ModelId=474BBB29014B
CXYDeal(){}
//##ModelId=474BBB29014C
virtual ULONG HH(){
printf("Hello");
return 0;
}
//##ModelId=474BBB29014E
virtual ULONG H1()
{
printf("Hello");
return 0;
}
DECLARE_CC_XX(CXYDeal);
//##ModelId=474BBB290150
BEGIN_CC_INTER();
BEGIN_DD_INTER(CXYDeal)
DD_INTER(IDeal)
DD_INTER(YDeal)
END_DD_INTER()
};
//内部类支持
//##ModelId=474BBB290157
class CIXYDeal : public Create<CIXYDeal>
{
//##ModelId=474BBB290178
DECLARE_CC_XX(CXYDeal);
//##ModelId=474BBB29017C
BEGIN_CC_INTER();
//内部接口支持
BEGIN_EE_INTER(ideal, IDeal)
METHOD_EE(H1)();
END_EE_INTER(ideal)
BEGIN_EE_INTER(ydeal, YDeal)
METHOD_EE(HH)();
END_EE_INTER(ydeal)
BEGIN_DD_INTER(CIXYDeal)
DDI_INTER(IDeal, ideal)
DDI_INTER(YDeal, ydeal)
END_DD_INTER()
};
//
ULONG CIXYDeal::ideal::H1()
{
printf("hello");
return 0;
}
ULONG CIXYDeal::ideal::AddRef()
{
return this->AddRef();
return 0;
}
ULONG CIXYDeal::ideal::Release()
{
return this->Release();
return 0;
}
ULONG CIXYDeal::ideal::QueryInterface(IID * iid, void **pThis)
{
return this->QueryInterface(iid, pThis);
return 0;
}
ULONG CIXYDeal::ydeal::HH()
{
printf("hello");
return 0;
}
ULONG CIXYDeal::ydeal::AddRef()
{
return this->AddRef();
return 0;
}
ULONG CIXYDeal::ydeal::Release()
{
return this->Release();
return 0;
}
ULONG CIXYDeal::ydeal::QueryInterface(IID * iid, void **pThis)
{
return this->QueryInterface(iid, pThis);
return 0;
}
void Test3()
{
GUID guid ;
CXDeal *p;
guid = IID_IDeal;
CXDeal::CreateInstance(&guid, (void **)&p);
p->H1();
p->Release();
CXX<CXDeal>pp ;
guid = IID_IDeal;
CXDeal::CreateInstance(&guid, (void **)&pp);
pp->H1();
CXX<CYDeal>py;
guid = IID_YDeal;
CYDeal::CreateInstance(&guid, (void **)&py);
py->HH();
CXX<IDeal> pi;
guid = IID_IDeal;
CXYDeal::CreateInstance(&guid, (void **)&pi);
pi->H1();
CXX<YDeal>ppy;
guid = IID_YDeal;
pi->QueryInterface(&guid, (void **)&ppy);
ppy->HH();
guid = IID_IDeal;
CXX<IDeal> ii;
CIXYDeal::CreateInstance(&guid, (void **)&ii);
ii->H1();
CXX<YDeal> iy;
guid = IID_YDeal;
ii->QueryInterface(&guid, (void **)&iy);
iy->HH();
}
//模板多重继承类结构
//
int main(int argc, char* argv[])
{
//多重继承,继承自模板
Test3();
return 0;
}