views:

48

answers:

2

Officially one should not use [out] parameters from COM functions unless the function succeeded this means that there are (at least) three ways to see if an [out] parameter can be used.

Consider the following interface

interface IFoo : IUnknown {
    HRESULT GetOtherFoo([out] IFoo** ppFoo);
    HRESULT Bar();
};

Which of the following ways would you recommend on using it?

1. Check return value

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr)) 
    other->Bar();

This makes me a bit nervous since a bug in IFoo could cause a NULL pointer dereferencing.

2. Check the output parameter

This depends on the fact that if a method fails it mustn't change any of the [out] parameters (if the parameter changed <==> it's safe to use it).

CComPtr<IFoo> other;
foo->GetOtherFoo(&other);
if (other) 
    other->Bar();

Note that this sort of happens anyway, CComPtr's destructor will call Release if the pointer isn't NULL so it can't be garbage.

3. The paranoid way, check both

CComPtr<IFoo> other;
HRESULT hr = foo->GetOtherFoo(&other);
if (SUCCEEDED(hr) && other) 
    other->Bar();

This is a bit verbose in my opinion.


P.S. See related question.

+2  A: 

COM server methods that return a success HRESULT, yet set some of their output parameters to NULL are not very common. There are a few cases (IClientSecurity::QueryBlanket comes to mind) where this is used, but usually the client may expect all output parameters to be non-NULL if the method returned successfully.

It is, after all, a matter of how the method is documented. In the default case, however, I would consider 1. to be a safe way to go.

Johannes Passing
+1  A: 

If you are willing to write more checks and make code a bit slower for making it more reliable option 3 is for you. Since you expect that there are bugs in the COM server it is quite reasonable to check against them.

sharptooth