ATL中的宏

来源:互联网 发布:锋芒网络剧百度云 编辑:程序博客网 时间:2024/05/21 15:38
 

#define BEGIN_OBJECT_MAP(x) static _ATL_OBJMAP_ENTRY x[]= { 

#define OBJECT_ENTRY(clsid, class ) { &clisd, class::UddateRegistry, / 

class::_ClassFactoryCreatorClass::CreateInstance / 

class::_CreatorClass::CreateInstace, / 

NULL, 0 , class::GetObjectDescription, / 

class::GetCategoryMap, class::ObjectMain }, 

#define END_OBJECT_MAP() { NULL, NULL, NULL,NULL,NULL,NULL,NULL,NULL}}; 

 

: 

BEGIN_OBJECT_MAP(ObjectMap) 

OBJECT_ENTRY(CLSID_IXXX, CIXXX) 

END_OBJECT_MAP( ) 

_ATL_OBJMAP_ENTRY结构示意 

 

pclsid 

pfnUpdateRegistry 注册和注销类函数 

pfnGetClassObject 类厂创建函数 

pfnCreateInstance 类实例创建函数 

pCF 

dwRegister 

pfnGetObjectDescription 

pfnGetCategoryMap 

pfnObjectMain 

 #define DECLARE_CLASSFACORY()  

DELARE_CLASSFACTORY_EX(CComClassFactory) 

对于进程内服务器为下面定义 

#define DECLARE_CLASSFACTORY_EX(cf)  

typedef CComCreator< CComObjectCached< cf > > _ClassFactoryCreatorClass; 

 

#define DECLARE_AGGREGATABLE(x) public:/ 

typedef CComCreator2< CComCreator< CComObject< x > >, CComCreator< CComAggObject< x > > > _CreatorClass; 

这宏说明在类CComCoClass 

有如下成员: _ClassFactoryCreatorClass  

_CreatorClass 

注意到: 

template <class T1, class T2> 

class CComCreator2 

{ 

public: 

 static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) 

 { 

  ATLASSERT(*ppv == NULL); 

  return (pv == NULL) ?  

   T1::CreateInstance(NULL, riid, ppv) :  

   T2::CreateInstance(pv, riid, ppv); 

 } 

}; 

 

我们将创建一个实例并且在整个服务器生命周期内拥有它,一旦被除数请求就提交它的引用 

template <class Base> 

class CComObjectCached : public Base 

{ 

public: 

 typedef Base _BaseClass; 

 CComObjectCached(void* = NULL){} 

 STDMETHOD_(ULONG, AddRef)() 

 { 

  m_csCached.Lock(); 

  ULONG l = InternalAddRef(); 

  if (m_dwRef == 2) 

   _Module.Lock(); 

  m_csCached.Unlock(); 

  return l; 

 } 

 STDMETHOD_(ULONG, Release)() 

 { 

  m_csCached.Lock(); 

  InternalRelease(); 

  ULONG l = m_dwRef; 

  m_csCached.Unlock(); 

  if (l == 0) 

   delete this; 

  else if (l == 1) 

   _Module.Unlock(); 

  return l; 

 } 

//_InternalQueryInterface这一个函数在宏中定义了 

 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) 

 {return _InternalQueryInterface(iid, ppvObject);} 

 

 CComGlobalsThreadModel::AutoCriticalSection m_csCached; 

}; 

 

所有类的基类,实现了IUnknown的行为,还有聚合等行为 

class CComObjectRootBase 

{ 

public: 

 CComObjectRootBase() 

 { 

  m_dwRef = 0L; 

 } 

 HRESULT FinalConstruct() 

 { 

  return S_OK; 

 } 

 HRESULT _AtlFinalConstruct() 

 { 

  return S_OK; 

 } 

 void FinalRelease() {} 

 void _AtlFinalRelease() {} 

 

  static void WINAPI ObjectMain(bool /* bStarting */) {} 

 

 static HRESULT WINAPI InternalQueryInterface(void* pThis, 

  const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) 

 { 

  //使用了全局函数和全局变量_Module中的函数 

 } 

 ULONG OuterAddRef() 

 { 

  return m_pOuterUnknown->AddRef(); 

 } 

 ULONG OuterRelease() 

 { 

  return m_pOuterUnknown->Release(); 

 } 

 HRESULT OuterQueryInterface(REFIID iid, void ** ppvObject) 

 { 

  return m_pOuterUnknown->QueryInterface(iid, ppvObject); 

 } 

 void SetVoid(void*) {} 

 void InternalFinalConstructAddRef() {} 

 void InternalFinalConstructRelease() 

 { 

  ATLASSERT(m_dwRef == 0); 

 } 

 union 

 { 

  long m_dwRef; 

  IUnknown* m_pOuterUnknown; 

 }; 

}; 

当创建者创建一个类厂实例会调用SetVoid方法,给函数指针赋值,这个指针用于创建一个类的实例. 

1. 首先COM库的调用,链接到导出函数DllGetClassObject 

2. 调用全局变量的GetClassObject,这个函数调用全局函数AtlModuleGetClassObject, 在这个函数中有一句 

 

3. pEntry->pfnGetClassObject(pEntry->pfnCreateInstance, IID_IUnknown, (LPVOID*)&pEntry->pCF) 

 

4. 把这个指针pEntry->pfnCreateInstance传递进去 

 

5. 查看对象映射表得知pfnGetClassObjectr 的值为 

6. class::_ClassFactoryCreatorClass::CreateInstance 

7. 即为 CComCreator< CComObjectCached< CComClassFactory > > ::CreateInstance 

8. 下面来看看CreateInstance函数的实现,大致过程是这样: 

{ 

CComObjectCached < CComClassFactory > * p = NULL; 

P = new CComObjectCached < CComClassFactory >(pEntry->pfnCreateInstance) //构造函数空 

执行SetVoid() 

p->SetVoid(pEntry->pfnCreateInstance) 

} 

 

9. 执行其父类的SetVoid函数,即为CComClassFactory,其代码为: 

 void SetVoid(void* pv) 

 { 

  m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv; 

 } 

10. 在内部使用类厂的指针调用如下代码 

pIFactory->CreateInstance(…………….),其执行为 

 hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); 

 

 

11. pfnCreateInstance 所指向的函数为 

CComCreator2< CComCreator< CComObject< T > >, CComCreator< CComAggObject< T > > > ::CreateInstance 其函数实现为: 

static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) 

 { 

  ATLASSERT(*ppv == NULL); 

  return (pv == NULL) ?  

   T1::CreateInstance(NULL, riid, ppv) :  

   T2::CreateInstance(pv, riid, ppv); 

 } 

 

12. 下面来看看CComCoClass的定义 

template <class T, const CLSID* pclsid = &CLSID_NULL> 

class CComCoClass 

{ 

public: 

 DECLARE_CLASSFACTORY() 

展开为: 实质上为一个CComCreator的一个成员 

typedef CComCreator< CComObjectCached < CComClassFactory > > _ClassFactoryCreatorClass; 

 

 DECLARE_AGGREGATABLE(T) 

展开为: 实质上为一个CComCreator2的一个成员 

typedef CComCreator2< CComCreator< CComObject< T > >, CComCreator< CComAggObject< T > > > _CreatorClass; 

 

typedef T _CoClass; 

 

template <class Q> 

 static HRESULT CreateInstance(IUnknown* punkOuter, Q** pp) 

 { 

  return T::_CreatorClass::CreateInstance(punkOuter, __uuidof(Q), (void**) pp); 

 } 

 template <class Q> 

 static HRESULT CreateInstance(Q** pp) 

 { 

  return T::_CreatorClass::CreateInstance(NULL, __uuidof(Q), (void**) pp); 

 } 

}; 

 

 

template <class T1> 

class CComCreator //T1是一个类,在调用了这个类的很多方法 

{ 

public: 

 static HRESULT WINAPI CreateInstance(void* pv, REFIID riid, LPVOID* ppv) 

 { 

  ATLASSERT(*ppv == NULL); 

  HRESULT hRes = E_OUTOFMEMORY; 

  T1* p = NULL; 

  ATLTRY(p = new T1(pv)) 

  if (p != NULL) 

  { 

   p->SetVoid(pv); 

   p->InternalFinalConstructAddRef(); 

   hRes = p->FinalConstruct(); 

   p->InternalFinalConstructRelease(); 

   if (hRes == S_OK) 

    hRes = p->QueryInterface(riid, ppv); 

   if (hRes != S_OK) 

    delete p; 

  } 

  return hRes; 

 } 

}; 

 

类厂的实现 

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) 

 { 

  ATLASSERT(m_pfnCreateInstance != NULL); 

  HRESULT hRes = E_POINTER; 

  if (ppvObj != NULL) 

  { 

   *ppvObj = NULL;    

   if ((pUnkOuter != NULL) && !InlineIsEqualUnknown(riid)) 

   { 

    hRes = CLASS_E_NOAGGREGATION; 

   } 

   else 

    hRes = m_pfnCreateInstance(pUnkOuter, riid, ppvObj); 

  } 

  return hRes; 

 } 

 STDMETHOD(LockServer)(BOOL fLock) 

 { 

  if (fLock) 

   _Module.Lock(); 

  else 

   _Module.Unlock(); 

  return S_OK; 

 } 

 void SetVoid(void* pv) 

 { 

  m_pfnCreateInstance = (_ATL_CREATORFUNC*)pv; 

 } 

 _ATL_CREATORFUNC* m_pfnCreateInstance; 

}; 

原创粉丝点击