通过COM边界传递CComSafeArray

Passing a CComSafeArray across a COM boundary

本文关键字:CComSafeArray 边界 COM 通过      更新时间:2023-10-16

我正试图(I)在COM边界上获得一个long的安全数组,以及(ii)为了方便起见,使用CComSafeArray。

我的问题是,在设置COM属性后,我会出现不可预测的崩溃(请参阅下面的pPrologue->EligibleProducts=var;)。我发现很难理解如何使用微软文档中的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);

if(newVal.vt|(vt_ARRAY&vt_I4))

这并不像你想象的那样。这个条件总是成立的。您正在寻找if (newVal.vt == VT_ARRAY | VT_I4)

put_EligibleProducts中,您已将Attach的CComSafeArray添加到VARIANT内的指针,但尚未将其分离。当wrapper超出范围时,它会破坏安全数组。然后,调用者试图通过VariantClear第二次销毁它。这是你遇到困难的直接原因。