ATL组件模拟之多接口实现和内部类实现多接口

19 篇文章 0 订阅

对于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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值