views:

110

answers:

2

Hi,

Can somebody please explain how the memory allocation/de-allocation occurs when we passing values between COM object and VB.

My Concerns are: 1.

IMyInterface::Method1 ([in] BSTR* pVal, [in] SAFEARRAY(BSTR)* pArray);

do we need to free the allocated memory for above parameters inside COM object ?

2.

IMyInterface::Method2 ([in, out] BSTR* pVal);

In this case, Will the VB take care of freeing memory for the COM return values ? (COM object allocates memory for these return values)

3.

IProxy_MyInterface::Event1 ([in] BSTR* pVal);

Once the event is handled inside VB, again, will de-allocation of memory of parameters be taken care by VB ?

Appreciate your help.

Thank you

A: 

[in] parameters must be allocated by the caller and freed by the caller unless the API documentation specifically says otherwise.

The [in, out] parameter is less clear, since this is a BSTR* it's possible that the BSTR that you pass in will be freed and a different BSTR returned, so you should free the BSTR that is returned rather than the one you passed in.

[out] and [out, retVal], imply a transfer of ownership of the memory, the function allocates the memory and the caller is then responsible for freeing the memory.

For BSTR in C/C++ COM you would use SysAllocString and SysFreeString to allocate and free.

John Knoeller
thanks for the clarification, If I use "[out]/ [out, retVal] BSTR*", then is it callee's responsibility to free the memory ? I think it is so, since once a value is returned, caller has no control over the function. Please explain.
Nimo
A: 

VB6 has three cases of string parameter declaration -- ByVal param As String, ByRef param As String and Function() As String. First one in IDL maps to [in] BSTR param, second one to [in, out] BSTR *param, third one to [out, retval] BSTR *retval.

There is no way VB6 can declare [in] BSTR *, nor [out] BSTR * params but it can still consume these i.e. it can call methods (on a VC) class that has params declared as out-only or any other IDL supported way.

Also note that BSTR itself is a typedef'd pointer, something like wchar_t *, so BSTR * is actually wchar **. The IDL needs an pointer for out params so you can't declare [out] int param and [out] BSTR param is also strange.

Once [in] BSTR * confusion is clear (it's needless weird double indirection required for out params but not for input only), the simple rule is that once you have a * in the param declaration then the caller has to free it after the method call if it's not NULL already.

[in, out] SAFEARRAY(BSTR)* pArray maps to ByRef pArray() As String in VB6 and you can't change this to ByVal i.e. the * is required by VB6 so it can't be in-only and the caller has to deallocate the safe array. The is no in-only safe array.

wqw