views:

97

answers:

2

We have the following interface:

[object, uuid("uuidhere"), dual ]
interface IInterface : IDispatch
{
    [id(1), propget] HRESULT CoolProperty( [out, retval] BSTR* result );
}

Now there's a minor problem. On one hand the parameter is "out" and so any value can be passed as input, the parameter will become valid only upon the successful return. On the other hand, there's this MSDN article which is linked to from many pages that basically says (the last paragraph) that if any function is passed a BSTR* it must free the string before assigning a new string.

That's horrifying. If that article is right it means that all the callers must surely pass valid BSTRs (maybe null BSTRs), otherwise BSTR passed can be leaked. If the caller passed a random value and the callee tries to call SysFreeString() it runs into undefined behavior, so the convention is critical.

Then what's the point in the [out] attribute? What will be the difference between the [in, out] and [out] in this situation?

Is that article right? Do I need to free the passed BSTR [out] parameter before assigning a new one?

+2  A: 

You should expect the client to follow the contract, honor the [out] attribute and not pass an initialized BSTR that needs to be freed. Double-checking and expecting a NULL is not okay, the contract also doesn't require the client to pass a pointer to an initialized memory location. You'd most typically get a pointer to a BSTR variable allocated on the stack frame. It is likely to contain random garbage, although a defensive programmer would set it to NULL.

It is otherwise incompatible with OLE Automation. Only [out,retval] and [in,out] are supported, no doubt to avoid this particular trap.

Hans Passant
+2  A: 

The documentation states that OUT pointers should never be freed by the callee so, IMHO, you'd be better abiding to the specification.

Best

Vagaus