我有一个COM功能:
GetData(SAFEARRAY ** pRetVal)
并遵循遗留代码:
CComSafeArray<double> saDataArray;
hr = pmyInterface->GetData(&saDataArray.m_psa);
SafeArrayLock(saDataArray);
我怀疑手动管理锁是否合适。当m_psa
NULL
GetData
被LPSAFEARRAY psa;
CComSafeArray<double> saDataArray;
hr = pmyInterface->GetData(&psa);
saDataArray.Attach(psa);
返回时,该代码是否会崩溃?
以下代码怎么样?那更好吗?
GetData
修改
我测试了上面的两个代码。有一点不同。如果NULL
返回Attach
,则直接NULL
,如果没有E_INVALIDARG
检查,则会调用异常。第一个版本将返回E_INVALIDARG
。我的问题仍然存在,您是否更喜欢更高版本,因为它使用SafeArray对象来维持计数,而不是混合它?
EDIT2:
如果由于某种原因我选择第一个版本,是否可以忽略saDataArray
返回值?当某些代码稍后使用此{{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
。