10

In some of the IDL I work with I have noticed that there are 2 conventions for marking return values in methods - [in, out] and [out, retval].

It appears that [in, out] is used when there are multiple return values, for example:

HRESULT MyMethod(
    [in] long InputParam, 
    [in, out] long* OutputParam1, 
    [in, out] long* OutputParam2
);

It appears that [out, retval] is used when there is only a single return value, for example:

HRESULT MyMethod2(
    [in] long InputParam, 
    [out, retval] long* OutputParam1
);

Is this a COM IDL convention or just a convention in the code I am working with?

Is there a functional difference in the code that will be generated from the 2 notations, or are they completely interchangeable?

LeopardSkinPillBoxHat
  • 28,915
  • 15
  • 75
  • 111

2 Answers2

28

[in, out] means that a valid value is passed when the method is called and a valid value is there (where the pointer points) when the method returns success. [out] means that the value pointed to can be whatever when the method is called but it will be valid when the method returns success. Both [out] and [in, out] parameters must be pointers - their values are unchanged and valid and the validity requirements only apply to the variables they point to.

[out, retval] is a syntactic sugar to indicate that when creating a Native COM Support wrapper this very parameter should be converted to a return value. For example

HRESULT MyMethod( [out] long* OutParam1, [out, retval] long* OutParam2 );

becomes

long IWrappedInterface::MyMethod( long* OutParam1 );

If you don't mark it [retval] the wrapper will contain a method with the original signature:

HRESULT IWrappedInterface::MyMethod( long* OutParam1, long* OutParam2 );

Only the last one [out] parameter can be marked as [out, retval]. [in, out] parameters can't be marked as [retval].

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • I'd like to add that `[in,out]` may not be handled correctly by all languages (more specifically, old-school Visual Basic, not sure about .NET). – Kim Gräsman Oct 16 '09 at 09:58
  • I'm wondering if [out, retval] is against best practice to define COM interfaces since there is no way to get error code (HRESULT) if execution fails? – dave May 28 '14 at 14:47
  • @dave: If execution fails an appropriate HRESULT is returned. If you're calling the method via "raw interface" the signature is such that `HRESULT` is returned and you can check it. If you're calling a Native COM Support wrapper which returns something other than `HRESULT` then this wrapper will have a check inside it and call `_com_issue_error()` which will be mapped onto some function that throws an exception. So this isn't a problem. – sharptooth May 29 '14 at 07:04
  • Elaborating on @KimGräsman's comment: Visual Basic ("classic"?) doesn't support `[in, out]`. An `[in, out]` parameter will be handled by Visual Basic code implementing the method as if it were `[out]`. Which means that whatever value the parameter points at when the method is called will be discarded and overwritten without checking, possibly causing a leak. Sometimes it doesn't matter (e.g. parameter points at local int), and sometimes it does (parameter pointing at a BSTR) – Euro Micelli Aug 08 '15 at 17:13
0

Another difference is how this will show up in a PIA in .NET code.

[out, ret] will show up as a return value in .NET.

[out] will show up an argument on the method in .NET.

JeanP
  • 41
  • 4