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

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • It's no secret what keeps CIOs up at night. Mobile, cloud, data, security, and social have become the "five imperatives," the drivers of business progress, innovation, and competitive differentiation. Business leaders around the world want to hear how other companies are succeeding. How are they applying the latest technologies? How did they get started? What outcomes are they achieving? Read this online magazine for success stories from organizations like the NBA, Pfizer, and San Jose State University as they …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds