A Pure C++ Implementation of a COM Smart Pointer

Introduction

CComPtr wraps any interface pointer and will call AddRef() and Release() properly. That is, you don't need to worry about the life cycle of your COM interface pointer.

Am I Re-Inventing Something Here?

  1. ATL does provide a COM smart pointer class named CComQIPtr, but it uses some ATL-specific funtions inside so that it can NOT be used outside the ATL environment.
  2. Visual C++ does provide the _com_ptr_t and _bstr_ptr_t helper classes to support smart the COM pointer feature, but it only works on the Microsoft Visual C++ Compiler, without which you cannot benefit.
  3. My CComPtr provides a compiler-independent, smart pointer solution. It is currently used in our kernal driver project and well-tested.

Illustration

Note: INTERFACE & piid are passed into the CComPtr class through template parameters.

CComPtr has four constructors to meet different requirements:

  • CComPtr(): Simply a constructor; does nothing.
  • CComPtr(INTERFACE* lPtr): Constructs a new CComPtr object with an existing interface pointer. After that, this new CComPtr object can be used as an interface pointer itself.
  • CComPtr(IUnknown* pIUnknown, IID iid): Constructs a new CComPtr object with an IUnknown pointer and an IID; these represent the interface you are interested in. Internally, a constructor will call pIUnknown->QueryInterface to fetch the interface pointer according to the IID.
  • CComPtr(const CComPtr<INTERFACE, piid>& RefComPtr): This contsructor takes another existing CComPtr object as a parameter. After that, clone the old CComPtr object.

CComPtr has one destructor; it will release the interface pointer.

~CComPtr(){ if (m_Ptr) { m_Ptr->Release(); m_Ptr = NULL; } }

CComPtr has five operators:

  • Operator INTERFACE*: Returns the interface pointer wrapped by the CComPtr class.
  • Example:

    CComPtr<IWavePciStream> m_wavePciStreamPtr;
    IWavePciStream* pWavePciStream =
       (IWavePciStream*)m_wavePciStreamPtr;
    
  • Operator *: Fetches the interface object wrapped by the CComPtr class.
  • Example:

    CComPtr<IWavePciStream> m_wavePciStreamPtr;
    IWavePciStream wavePciStream = *m_wavePciStreamPtr;
    
  • Operator &: Fetches the pointer to an interface pointer wrapped by the CComPtr class.
  • Example:

    CComPtr<IWavePciStream> m_wavePciStreamPtr;
    IWavePciStream** ppWavePciStream = &m_wavePciStreamPtr;
    
  • Operator ->: Makes a CComPtr object act as a TRUE interface pointer.
  • Example:

    CComPtr<IWavePciStream> m_wavePciStreamPtr;
    m_wavePciStreamPtr->AnyPciStreamMethods();
    
  • Operator =: Transfers exsiting interface pointer information to a new CComPtr object. This operator has three different parameters:
    1. There is an INTERFACE* in the parameter.
    2. There is another CComPtr object in the parameter.
    3. There is an interface pointer to IUnknown in the parameter. It will be used to query other interface pointer defined by piid.

CComPtr has another three methods:

  • Attach: Attaches an existing interface pointer to a CComPtr object
  • Detach: Detaches an interface pointer from a CComPtr object
  • Release: Releases the wrapped interface pointer explicitly

CComPtr is implemented in pure C++. That is, it does not depend on any specific C/C++ compiler and can be compiled under any ANSI C/C++-compliant compiler. I have tested in VC++ 6.0. I do believe it works in GNU C/C++ and MAC CodeWarrior.



About the Author

Skeeter Xu

Software Architect from Intel R&D Center, Shanghai China. Before that, I was working in Singapore for 8 years focusing on all kinds of Windows platform development - from firmware, device drive to application level.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-Demand Oracle Webcast As disruption driven by the cloud, mobile and open source accelerates, developers and development organizations are taking a larger role in technology decision-making at the firms they work for. But what choices are are these organizations actually making? Join Forrester Vice President & Principal Analyst Jeffrey Hammond for an examination of the choices developers are making, trends in programming language adoption, adoption of frameworks, and how development projects are moving to …

  • Enterprises are typically overwhelmed with incredible volumes of alerts that lack context and are not easily correlated across their technology stacks and silos. It can be incredibly challenging for large enterprises to detect and resolve incidents across multiple environments. When enterprises do detect challenges, communicating and acting efficiently through the right tools can be a daunting proposition. IT teams can provide real value if they collaborate and use agile methods for enterprise DevOps to move …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date