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?
- 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.
- 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.
- 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;
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; IWavePciStream wavePciStream = *m_wavePciStreamPtr;
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; IWavePciStream** ppWavePciStream = &m_wavePciStreamPtr;
Example:
CComPtr<IWavePciStream> m_wavePciStreamPtr; m_wavePciStreamPtr->AnyPciStreamMethods();
- There is an INTERFACE* in the parameter.
- There is another CComPtr object in the parameter.
- 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.