Interesting Problem Related to a Temporary VARIANT – Personal Findings – Part 1
There was recently a question posted on the COM forum here at CodeProject and it involved a temporary VARIANT object being created (in a VB client code) to fill an [in, out, optional] VARIANT* parameter of a method call.
The person who posted the original question was one GuimaSun and his COM server code was listed as follows :
STDMETHODIMP CDCSClient::CallService( VARIANT *p1 )
{
...
...VariantClear( p );
VariantInit( p );
p->vt = VT_BSTR | VT_BYREF;
BSTR *pBSTR = new BSTR;
*pBSTR = SysAllocString( L"abc" );
p->pbstrVal = pBSTR;
...
...
...
}
His VB client code was :
For i = 1 To 1000
Dim myInt As Integer
myInt = 3
ret = client.CallService(myInt)
Next
Apparently, his COM server code was changing the Variant Type of the input VARIANT pointer "p" and assigning it to contain a BSTR.
His VB code experienced memory leaks due to the BSTR (created inside his COM CallService() method) not being ::SysFreeString()'ed.
After much discussion with several members of the forum, Vi2 came up with a code suggestion for GuimaSun as follows :
STDMETHODIMP CDCSClient::CallService(/*[in,out]*/ VARIANT *p)
{
if (V_VT(p) == (VT_VARIANT | VT_BYREF))
{
// only here you can change the type of passed variable (see VB example below)
VARIANT *p2 = V_VARIANTREF(p);
p2->vt = VT_BSTR;
p2->bstrVal = SysAllocString( L"abc" );
return S_OK;
}
}Dim v As Variant
v = 1
Debug.Print TypeName(v) & " " & v
Call obj.CallService(v)
Debug.Print TypeName(v) & " " & v
Basically, only a VARIANT of Variant Type (VT_VARIANT | VT_BYREF) can be modified to be of a different VT.
_______________________
Tip Courtesy :- Lim Bio Liong