2013-04-22 50 views
1

我有一個COM功能:這是CComSafeArray的使用不好嗎?

GetData(SAFEARRAY ** pRetVal) 

及以下的遺留代碼:

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

我懷疑,如果這是很好的手動管理鎖。當m_psa被返回爲NULLGetData時,該代碼是否會崩潰?

下面的代碼如何?那個更好嗎?

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

編輯: 我測試的兩種代碼的上方。有一個區別。如果GetData返回NULL,直接Attach它沒有NULL檢查將調用一個異常。第一個版本將返回E_INVALIDARG。我的問題仍然存在,你更喜歡後來的版本,因爲它使用SafeArray對象來維持計數,而不是混合它?

EDIT2: 如果出於某種原因,我選擇的第一個版本,是沒關係忽略E_INVALIDARG返回值?當某些代碼稍後使用saDataArray時會有什麼副作用嗎?

+0

ATL庫或MS工具中的任何其他位置沒有'SafeArray'類型。你可能意思是'LPSAFEARRAY'。此外,ATL :: CComSafeArray提供了一種獲取out-val用法的內部指針地址的方法。 [CComSafeArray :: GetSafeArrayPtr()](http://msdn.microsoft.com/en-us/library/1s10dhw5(v = vs.71).aspx) – WhozCraig 2013-04-22 09:33:06

+0

我不知道它是否可能是重複的[這個問題](http://stackoverflow.com/questions/1778491/how-does-one-return-a-local-ccomsafearray-to-a-lpsafearray-output-parameter)... – 2013-04-22 09:41:36

+0

謝謝,這是正確的 – Archer 2013-04-22 09:43:34

回答

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函數調用。但混合兩者不是質量好的代碼,國際海事組織。

注意,第二個方法是不同的,因爲你第一次使用的原料SAFEARRAY,使GetData()方法填充它,然後你.Attach()它的CComSafeArray C++ RAII包裝,過戶(「移動語義」 )到那個包裝。然後可以使用包裝器方法來操作數組。

另外,在生產質量代碼中,我不會忽略錯誤HRESULT s。

+0

沒錯,它是LPSAFEARRAY。似乎大多數人更喜歡使用CComSafeArray來處理鎖定。但我的問題仍然存在,可以忽略E_INVALIDARG嗎? – Archer 2013-04-22 09:49:11

+0

不,如果從Attach()得到E_INVALIDARG,那是因爲該函數的作者認爲它的合約的一部分,它的輸入參數是非空的。所以你應該保護你的調用附加一個空指針檢查,而不是調用和忽略結果。這將是更安全的(因爲你不會忽略捕獲其他潛在的錯誤代碼),更可讀的anwyay。 – 2014-04-08 21:11:33