Reputation: 386
This is a follow up to this question
When declaring interfaces in IDL, there are at least two ways to return values from an interface: [out]
and [out, retval]
.
When [out, retval]
is used, the COM wrapper makes the marked parameter the return value and no HRESULT
is returned from the method anymore. The question is how then one obtains the HRESULT
to test if the COM call succeeds or not? And, from an COM server design standpoint, is it generally considered bad practice to not return HRESULT
on a COM method call?
Upvotes: 1
Views: 278
Reputation: 170489
Regardless of whether the parameter is declared as [out]
or [out, retval]
the HRESULT
will be returned to the caller side. What happens next greatly depends on the middleware between the actual caller code and COM.
If it's .NET code then the HRESULT
will be checked by the .NET generated wrapper and an exception will be thrown and the only solution is to catch and interpret exceptions which can be a lot of pain because different HRESULT
s will be translated to different exceptions.
If it's something more old school like for example Visual C++ Native COM support then you have options. The default is that Native COM Support generates a wrapper for each method with [out, retval]
parameter which now returns the type of that parameter and HRESULT
is checked inside the wrapper and perhaps _com_issue_error()
is called to throw an exception and the original HRESULT
is passed into _com_issue_error()
and the exception object from where you can retrieve it. It can be that handling exceptions for every COM method call adds clutter to your code and then you can use raw_interfaces_only
with #import
directive and then now wrappers are generated - you will have the original interface presented to you. It's up to you which you choose - HRESULT
s checked inside wrappers or having no wrappers.
Anyway you will have means to know there was an error. Using [out, retval]
is by no means a bad practice.
Upvotes: 2
Reputation: 941635
There's an important difference, it depends on the language runtime support in the client code. Many of them, like .NET or a scripting language, will modify the signature of the function and make it look like it is a function that returns the value that you've annotated with [retval]. And will hide the HRESULT, automatically triggering an exception when you return a failure code. This can make the client code look a lot more natural.
And yes, you should always implement STDMETHOD, such language runtimes tend to require it. Also a hard requirement when the client code wants to use late binding and when the function call needs to traverse an apartment boundary (i.e. getting marshaled from one thread to another or crossing a process or machine boundary), something that's not in your control.
Upvotes: 2