2
我試圖(i)爲了方便起見跨越COM邊界獲得longarray的safearray,並(ii)使用CComSafeArray。跨COM邊界傳遞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);
分離確實解決了問題。事實上,既不附加也不分離工作(即只是將數組傳遞給包裝器構造函數),那麼它不會控制 - 這正是我試圖達到的目的(同樣感謝其他修復)。 –
當您將數組傳遞給構造函數時,「CComSafeArray」將複製數據;然後再銷燬該副本。看看你是否願意承擔這種開銷。 –
再次感謝您的澄清。這裏的表現不是問題,所以我認爲我會堅持做一個副本。也許有時間去掌握ATL內部... –