browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

COM学习笔记(3)

Posted by on 2004 年 04 月 04 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

IUnknown

IDL描述:

interface IUnknown
{
  HRESULT QueryInterface([in]REFIID iid, [out]void** ppv);
  ULONG AddRef(void);
  ULONG Release(void);
}

构造函数、AddRef、Release的某种实现可能

C++代码
  1. class CUnknown : public IUnknown   
  2. {   
  3. public:   
  4.   CUnknown();   
  5.   ~CUnknown();   
  6.   virtual HRESULT QueryInterface(const IID& iid, void** ppv);   
  7.   virtual ULONG AddRef();   
  8.   virtual ULONG Release();   
  9. private:   
  10.   int m_Ref;   
  11. };   
  12. CUnknown::CUnknown()   
  13. {   
  14.   m_Ref = 0;   
  15.   // 其它的初始化工作   
  16. }   
  17. ULONG CUnknown::AddRef()   
  18. {   
  19.   m_Ref++;   
  20.   return (ULONG)m_Ref;   
  21. }   
  22. ULONG CUnknown::Release()   
  23. {   
  24.   m_Ref–;   
  25.   if (m_Ref == 0)   
  26.   {   
  27.     delete this;   
  28.     return 0;   
  29.   }   
  30.   return (ULONG)m_Ref;   
  31. }  

接口查询

QueryInterface可用于获得对象所支持的任何一个接口指针。

HRESULT QueryInterface([in]REFIID iid, [out]void** ppv);

iid为查询接口的IID,ppv用来保存查询得到的接口指针。

返回值:
S_OK:查询成功完成。
E_NOINTERFACE:对象不支持要查询的接口。
E_UNEXPECTED:意外错误。

查询原则:
1、对于同一个对象的不同接口指针,查询得到的IUnknown接口必须完全相同。
2、对一个接口查询自身必须是成功的。
3、从第一个接口查询到第二个接口,则从第二个接口查询第一个接口应成功。
4、从第一个接口查询到第二个接口,从第二个接口查询到第三个接口,则一定能从第三个接口查询到第一个接口。
5、查询借口成功与否应该与时间无关。

QueryInterface的某种实现

C++代码
  1. HRESULT CMyObject::QueryInterface(const IID& iid, void** ppv)   
  2. {   
  3.   if (iid == IID_IUnknown)   
  4.   {   
  5.     *ppv = (IMyInterface *)this;   
  6.    ((IMyInterface *)(*ppv))->AddRef();   
  7.   }   
  8.   else if (iid == IID_IMyInterface)   
  9.   {   
  10.     *ppv = (IMyInterface *)this;   
  11.     ((IMyInterface *)(*ppv))->AddRef();   
  12.   }   
  13.   else if (iid == IID_Another)   
  14.   {   
  15.     *ppv = (IAnother *)this;   
  16.     ((IAnother *)(*ppv))->AddRef();   
  17.   }   
  18.   else  
  19.   {   
  20.     *ppv = NULL;   
  21.     return E_NOINTERFACE;   
  22.   }   
  23.   return S_OK;   
  24. }  

订阅本站

没有评论

(Required)
(Required, will not be published)