Peter
10/20/2008 2:38:00 AM
<vaclavpich@atlas.cz> wrote in message news:a86624e5-ceef-4c5c-a369-21f67fb935e4@d31g2000hsg.googlegroups.com...
> CObject::CObject()
> {
> // 1) if ( FAILED( LoadLibrary(...) )) throw exception1;
>
> // 2) if ( FAILED(CoInitialize( 0 )) throw exception2;
>
> // 3) if ( FAILED( CoCreateInstance(....))) throw exception3;
> }
>
> CObject::~CObject()
> {
> // 1) release COM interface
>
> // 2) CoUninitialize();
>
> // 2) FreeLibrary
> }
you should put the separate objects (HANDLE returned by LoadLibrary, CoInitialize()/CoUninitialize() and CoCreateInstance()) into separate classes and combine these classes into base-class or member-class relationships.
Doing it this way you don't have to clean up yourself anymore but rely on the code generation features of the compiler. And you can reuse these classes next time you're calling these functions.
And the caller of you'r code will get rich error information.
class CPLoadLibrary
{ private:
HINSTANCE h;
public:
inline CPLoadLibrary(const _TCHAR *pName)
{ if (!(h = LoadLibrary(pName)))
throwSystemException(
GetLastError(),
CString(_T("LoadLibrary(\"")) + CString(pName) + CString(_T("\")")));
}
inline ~CPLoadLibrary(void)
{ FreeLibrary(h);
}
inline void *getProcAddress(const char *pName)
{ void *p;
if (!(p = ::GetProcAddress(h, pName)))
throwSystemException(
GetLastError(),
_T("GetProcAddress()"));
return p;
}
inline operator HINSTANCE (void)
{ return h;
}
inline HINSTANCE getHINSTANCE(void)
{ return h;
}
};
template<class T, const IID *_piREFIID>
class CPCoCreateInstance
{ private:
T *m_p;
public:
inline CPCoCreateInstance(
REFCLSID _iCLSID,
IUnknown *_pUnkOuter,
DWORD _iClsContext)
{ HRESULT iRet;
m_p = 0;
if (FAILED(iRet = CoCreateInstance(_iCLSID, _pUnkOuter, _iClsContext, *_piREFIID, (void**)&m_p)))
throwSystemException(iRet, _T("CoCreateInstance()"));
if (!m_p)
throwSystemException(E_FAIL, _T("CoCreateInstance()"));
}
inline ~CPCoCreateInstance(void)
{ if (m_p)
m_p->Release();
}
inline operator T *(void)
{ return m_p;
}
inline T *getPtr(void)
{ return m_p;
}
inline T *detach(void)
{ T *pRet = m_p;
m_p = 0;
return pRet;
}
};
class CPCoInitializeEx
{ private:
public:
inline CPCoInitializeEx(void *_pReserved, DWORD _iFlags)
{ HRESULT iRet;
if (FAILED(iRet = CoInitializeEx(_pReserved, _iFlags)))
throwSystemException(iRet, _T("CoInitializeEx() failed!"));
}
inline ~CPCoInitializeEx(void)
{ CoUninitialize();
}
};