这个CComSafeArray使用不好吗?

时间:2013-04-22 09:10:13

标签: c++ com safearray

我有一个COM功能:

GetData(SAFEARRAY ** pRetVal)

并遵循遗留代码:

CComSafeArray<double> saDataArray;
hr = pmyInterface->GetData(&saDataArray.m_psa);
SafeArrayLock(saDataArray);

我怀疑手动管理锁是否合适。当m_psa NULL GetDataLPSAFEARRAY psa; CComSafeArray<double> saDataArray; hr = pmyInterface->GetData(&psa); saDataArray.Attach(psa); 返回时,该代码是否会崩溃?

以下代码怎么样?那更好吗?

GetData

修改 我测试了上面的两个代码。有一点不同。如果NULL返回Attach,则直接NULL,如果没有E_INVALIDARG检查,则会调用异常。第一个版本将返回E_INVALIDARG。我的问题仍然存在,您是否更喜欢更高版本,因为它使用SafeArray对象来维持计数,而不是混合它?

EDIT2: 如果由于某种原因我选择第一个版本,是否可以忽略saDataArray返回值?当某些代码稍后使用此{{1}}时会产生任何副作用吗?

1 个答案:

答案 0 :(得分:2)

您写道:

SafeArray * psa;
CComSafeArray<double> saDataArray;
hr = pmyInterface->GetData(&psa);
saDataArray.Attach(psa);

但我认为实际的代码应该是:

LPSAFEARRAY psa; // not "SafeArray *"
hr = pmyInterface->GetData(&psa);
CComSafeArray<double> saDataArray;
saDataArray.Attach(psa);

有关详细信息,请参阅this question

编辑:根据您的问题编辑更新答案。

我真的不喜欢你的第一个代码:

CComSafeArray<double> saDataArray;
hr = pmyInterface->GetData(&saDataArray.m_psa);
SafeArrayLock(saDataArray); // <--- Explicit lock on a CComSafeArray-wrapped array

事实上,一旦原始SAFEARRAY被赋予C ++ RAII包装器(CComSafeArray),从那个时间点开始,我只会使用这个包装器及其方法来操作数组。登记/> 如果你想对数组进行“手动”处理,只需从C ++包装器中.Detach(),并使用Win32 API函数调用。但混合两者并不是高质量的代码,IMO。

请注意,第二种方法不同,因为您首先使用原始SAFEARRAY,使GetData()方法填充它,然后.Attach()将其添加到CComSafeArray C ++ RAII包装器,将所有权(“移动语义”)转移到该包装器。然后可以使用包装器方法来操作数组。

此外,在生产质量代码中,我不会忽略错误HRESULT