ATL wants to internally manage the ref counts to your ATL based com object. To do this, it wraps your com object using a template class called CComObject. CComObject basically adds two extra layers to your com object. For debugging, it does make things a little bit more annoying, but it is supposed to manage the lifetime of your object for you.
The first thing to do is to remove the COM_MAP macros needed to set up all of the CComObject hooks. When you have an ATL generated COM object, it creates for you something like this in your header:
BEGIN_COM_MAP(CYourInterface)
COM_INTERFACE_ENTRY(IYourInterface)
END_COM_MAP()
Basically these macros help write your IUnknown implementation. Not really that big of a time saver as it is not that hard to implement IUnknown. The first step is to remove COM_MAP macro stuff from your header and swap it for the IUnknown definition. Here is one example that you see often:
STDMETHOD(QueryInterface)(IN REFIID riid, OUT void ** ppv);
STDMETHOD_(ULONG, AddRef)(void);
STDMETHOD_(ULONG, Release)(void);
Next, in your cpp file where you implement your com object, you will need to add the implementation of IUnknown. This too is almost boiler plate.
//////////////////////////////////////////////////////////////////////
// Implementation : IUnknown
//////////////////////////////////////////////////////////////////////
ULONG CYourInterface::AddRef()
{
return InterlockedIncrement(&m_cRef);
}
ULONG CYourInterface::Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
}
return cRef;
}
HRESULT CYourInterface::QueryInterface(REFIID riid, __deref_out_opt void **ppv)
{
HRESULT hr = S_OK;
if (ppv)
{
*ppv = NULL;
}
else
{
hr = E_INVALIDARG;
}
if (S_OK == hr)
{
if ((__uuidof(IUnknown) == riid) (riid == __uuidof(IYourInterface)))
{
AddRef();
*ppv = (IYourInterface *)this;
}
else
{
hr = E_NOINTERFACE;
}
}
return hr;
}
Finally make sure that you add a:
LONG m_cRef;
Member in your class, and make sure you initialize it to 1 in your constructor.
m_cRef(1)
No comments:
Post a Comment