Billy ONeal
Billy ONeal

Reputation: 106609

How does one wrap errors when calling COM in C++?

To follow typical COM procedure, whenever any error occurs, one must do the following:

  1. Check the HRESULT with FAILED or similar, to see if an error occured.
  2. Create a variable to hold an IErrorInfo (typically CComPtr<IErrorInfo>)
  3. Call ::GetErrorInfo(0, &var).
  4. Get the human readable version of that by calling IErrorInfo::GetDescription.
  5. Convert the BSTR into a std::wstring.
  6. Convert the std::wstring into some form of char const*.
  7. Throw a user defined exception type which derives from 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

Answers (2)

MSalters
MSalters

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

EdChum
EdChum

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

Related Questions