Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the COM server have to call SysFreeString() for an [out] parameter?

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?

like image 805
sharptooth Avatar asked Apr 28 '10 11:04

sharptooth


1 Answers

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 does not 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, only a defensive programmer would set it to NULL.

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

like image 83
Hans Passant Avatar answered Sep 28 '22 07:09

Hans Passant