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.
-
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.
-
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.
0 comments:
Post a Comment