我正在努力(i)在COM边界获得一个longs的安全阵列,以及(ii)为方便起见使用CComSafeArray。
我的问题是,在设置COM属性后,我遇到了不可预测的崩溃(请参阅下面的 pPrologue-> EligibleProducts = var; )。我发现很难理解如何使用Microsoft文档中的CComSafeArray,任何人都可以解决这个问题吗?提前谢谢!
在IDL中我有:
[propget, id(1), helpstring("property EligibleProducts")] HRESULT EligibleProducts([out, retval] VARIANT* pVal);
[propput, id(1), helpstring("property EligibleProducts")] HRESULT EligibleProducts([in] VARIANT newVal);
我的服务器代码是:
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;
}
我的主叫代码是:
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);
答案 0 :(得分:3)
if(newVal.vt |(VT_ARRAY&amp; VT_I4))
这不符合你的想象。这种情况总是如此。您正在寻找if (newVal.vt == VT_ARRAY | VT_I4)
在put_EligibleProducts
中,您有Attach
个CComSafeArray指向VARIANT内的指针,但您尚未分离它。当wrapper
超出范围时,它会破坏安全阵列。然后呼叫者尝试通过VariantClear
第二次销毁它。这是你遇到困难的直接原因。