Reputation: 106609
To follow typical COM procedure, whenever any error occurs, one must do the following:
HRESULT
with FAILED
or similar, to see if an error occured.IErrorInfo
(typically CComPtr<IErrorInfo>
)::GetErrorInfo(0, &var)
.IErrorInfo::GetDescription
.BSTR
into a std::wstring
.std::wstring
into some form of char const*
.std::exception
which exposes bits 1, 5, and 6 above.This all seems like a lot of boilerplate which has to go around pretty much every function call in COM.
I know the MSVC++ compiler provides a whole bunch of stuff to make messing with COM easier, such as ATL, and the compiler specific COM extensions _com_error
, _com_raise_error
and similar, but I'm not sure how to use these, or if they're even intended to be used by user code.
Are there any typical strategies that are used to manage this complexity in an exception safe and race condition safe manner?
Upvotes: 3
Views: 411
Reputation: 180235
The "obvious" solution is a ComException
. It can handle pretty much all steps - you just need to get obtain the HRESULT
for the ctor and throw the resulting object (steps 1 and 7).
You can even write
HRESULT check(HRESULT hr)
{
if(FAILED(hr)) throw ComException(hr);
return hr; // Success comes in different forms.
}
to take care of step 7 for you. E.g. check(pUnk->QueryInterface(MyID, &pMyIf));
Upvotes: 4
Reputation: 394409
I'm afraid there is no semi-standard way that is provided for you, even if you look at the sample apps and api usage on msdn they all show you have to manually do all the tedious HResult checking, checking if the IPtr is valid etc.. You will have to write your own function that wraps all of this so that you do not duplicate code, it shouldn't be a problem.
Upvotes: 1