Reputation: 99
I'm trying to (i) get a safearray of longs across a COM boundary and (ii) use CComSafeArray for convenience.
My problem is that I'm getting unpredictable crashes after setting the COM property (see pPrologue->EligibleProducts = var; below). I've found it very hard to understand how to use CComSafeArray from the Microsoft documentation, can anyone shed any light? Thank you in advance!
In the IDL I have:
[propget, id(1), helpstring("property EligibleProducts")] HRESULT EligibleProducts([out, retval] VARIANT* pVal);
[propput, id(1), helpstring("property EligibleProducts")] HRESULT EligibleProducts([in] VARIANT newVal);
My server code is:
STDMETHODIMP CPrologue::put_EligibleProducts(VARIANT newVal)
{
HRESULT hr = E_FAIL;
AFX_MANAGE_STATE(AfxGetStaticModuleState())
//start by clearing out any existing data
m_EligibleProducts.clear();
if(newVal.vt | (VT_ARRAY & VT_I4))
{
//construct a wrapper class with the passed in SAFEARRAY
CComSafeArray<long> wrapper;
wrapper.Attach(newVal.parray);
int iProductID = 0;
//loop through products and add them to our vector
int iCount = wrapper.GetCount();
for(int iIndex = 0; iIndex < iCount; iIndex++)
{
iProductID = wrapper.GetAt(iIndex);
if(iProductID > 0)
{
m_EligibleProducts.push_back(iProductID);
}
}
hr = S_OK;
return hr;
}
And my calling code is:
VARIANT var;
::VariantInit(&var);
var.vt = VT_ARRAY | VT_I4;
CComSafeArray<long> wrapper;
for(std::vector<long>::const_iterator it = products.begin(); it != products.end(); it++)
{
wrapper.Add(*it);
}
//get the SAFEARRAY from the wrapper
var.parray = wrapper.Detach();
//and store it on the appropriate business object
IProloguePtr pPrologue = pCustomer->Prologue;
**pPrologue->EligibleProducts = var;**
//clean up the variant (and hence SAFEARRAY)
::VariantClear(&var);
Upvotes: 3
Views: 1250
Reputation: 52621
if(newVal.vt | (VT_ARRAY & VT_I4))
This doesn't do what you seem to think it does. This condition is always true. You are looking for if (newVal.vt == VT_ARRAY | VT_I4)
In put_EligibleProducts
, you have Attach
ed CComSafeArray to the pointer inside VARIANT, but you haven't detached it. When wrapper
goes out of scope, it destroys the safearray. Then the caller attempts to destroy it the second time, by means of VariantClear
. This is the immediate cause of your difficulties.
Upvotes: 3