WEB开发网
开发学院软件开发VC 用ATL建立轻量级的COM对象(4) 阅读

用ATL建立轻量级的COM对象(4)

 2006-07-21 11:44:34 来源:WEB开发网   
核心提示:第一部分:为什么要使用ATL,第二部分:起步篇,用ATL建立轻量级的COM对象(4),第三部分:实现IUnknown,实现接口现在你已经积累了一些关于ATL线程模型方面的知识,下图展示了一个典型的基于ATL的类层次,图四 典型的基于ATL的类层次从下面的代码可以看出,下面我们来讨论ATL如何实现IUnknown,ATL

第一部分:为什么要使用ATL。

第二部分:起步篇。

第三部分:实现IUnknown。

实现接口

现在你已经积累了一些关于ATL线程模型方面的知识,下面我们来讨论ATL如何实现IUnknown。ATL最不直观的(同时也是最强大的)一个方面就是你要实现的类事实上都是不能被直接实例化的抽象类。实现一个从通用的IUnknown派生的C++类。但是在确定对象的运行环境之前,QueryInterface,AddRef 和 Release是不会有实质性代码的。这种灵活性使开发人员能实现对象的关键功能,如COM的聚合支持,tear-offs,堆和栈分配,服务器锁定等等。下图展示了一个典型的基于ATL的类层次。

图四 典型的基于ATL的类层次

从下面的代码可以看出,ATL中实现IUnknown的关键在于CComObjectRootBase 和 CComObjectRootEx。

CComObjectRoot 
 class CComObjectRootBase {
 public:
 // C++ 构造函数
  CComObjectRootBase() { m_dwRef = 0L; }
 
 // ATL 伪构造函数和伪析构函数
  HRESULT FinalConstruct() { return S_OK; } 
  void FinalRelease() {}
 
 // 内部Unknown函数(由派生类提供的InternalAddRef/Release)
  static HRESULT WINAPI InternalQueryInterface(void* pThis, 
       const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject) {
   HRESULT hRes = AtlInternalQueryInterface(pThis,pEntries,iid,ppvObject);
   return _ATLDUMPIID(iid, pszClassName, hRes);
  }
 
 // 外部Unknown函数
  ULONG OuterAddRef() { return m_pOuterUnknown->AddRef(); }
  ULONG OuterRelease() { return m_pOuterUnknown->Release(); }
  HRESULT OuterQueryInterface(REFIID iid, void ** ppvObject) 
  { return m_pOuterUnknown->QueryInterface(iid, ppvObject); }
 
 // ATL 创建者的钩子例程
  void SetVoid(void*) {}
  void InternalFinalConstructAddRef() {}
  void InternalFinalConstructRelease() {}
 
 // ATL 接口映射辅助函数
  static HRESULT WINAPI _Break(    void*, REFIID, void**, DWORD);
  static HRESULT WINAPI _NoInterface( void*, REFIID, void**, DWORD);
  static HRESULT WINAPI _Creator(   void*, REFIID, void**, DWORD);
  static HRESULT WINAPI _Delegate(  void*, REFIID, void**, DWORD);
  static HRESULT WINAPI _Chain(    void*, REFIID, void**, DWORD);
  static HRESULT WINAPI _Cache(    void*, REFIID, void**, DWORD);
 
 // 实际的引用计数或者指针返回到真实的Unknown
  union {
   long m_dwRef;
   IUnknown* m_pOuterUnknown;
  };
 };
 
 template <class ThreadModel>
 class CComObjectRootEx : public CComObjectRootBase {
 public:
  typedef ThreadModel _ThreadModel;
  typedef _ThreadModel::AutoCriticalSection _CritSec;
 
 // 内部 Unknown 函数(InternalQueryInterface 由 CComObjectRootBase提供)
  ULONG InternalAddRef() { return _ThreadModel::Increment(&m_dwRef); }
  ULONG InternalRelease()    { return _ThreadModel::Decrement(&m_dwRef); }
 
 // 对象级的锁定操作
  void Lock() {m_critsec.Lock();}
  void Unlock() {m_critsec.Unlock();}
 private:
  _CritSec m_critsec;
 };

1 2 3  下一页

Tags:ATL 建立 轻量级

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接