COM interfaces methods can return various HRESULT
values to signal invalid argument values passed. When do I return E_POINTER
and when E_INVALIDARG
?
As I understand if a method receives an index in an encapsulated collection and it is out of bounds that is E_INVALIDARG
. If a method receives an Interface**
pointer where it is meant to store a pointer to a newly created object that's E_POINTER
.
HRESULT CImpl::GetItem( long index; Interface** result )
{
if( result == 0 ) {
return E_POINTER;
}
if( index < 0 || index >= internalArray.size() ) {
return E_INVALIDARG;
}
*result = CreateWrapperObject( internalArray[index] );
return S_OK;
}
But what if it receives a WCHAR*
buffer with a file name as an "in" parameter and this WCHAR*
is null? Is this E_POINTER
or E_INVALIDARG
?
Or a method receives a pointer to some struct and is expected to fill the struct through that pointer and this pointer is null - is this E_POINTER
or E_INVALIDARG
?
HRESULT CImpl::SaveToFile( WCHAR* fileName )
{
if( fileName == 0 ) {
return // what to return here?
}
//... do actual work here
}
HRESULT CImpl::GetAttributes( Attributes* to )
{
if( to == 0 ) {
return // what to return here?
}
attributes->IsCool = getIsCool();
attributes->Color = RGB( 0, 255, 0 );
return S_OK;
}
What are the rules for when to return E_POINTER
and when E_INVALIDARG
when checking pointer type parameters?
You return E_POINTER
when the reference to the pointer of an out parameter is null, this consider to be an error code that indicates a bug in the program or in the interop layer.
You return E_INVALIDARG
when there is an application level on with the parameter for example out of range issue or parameter that collide with each other.
In Your case, in SaveToFile(...)
you should return E_INVLIADARG
since it is not valid to pass empty file name, and in GetAttributes(...)
you should return E_POINTER
(if it's an out param) because you cannot fill the value.
And yes, we all L-O-V-E com :)