2013-06-21 20 views
2

我有一個關於何時有必要使用SafeArrayAccessData來鎖定由託管代碼傳遞的SAFEARRAY的問題。 這是我們的代碼。 VARIANT由託管代碼傳遞,並帶有一個字符串數組。在代碼審查期間,有人建議使用SafeArrayAccessData/SafeArrayUnAccessData。但他不清楚爲什麼和有什麼好處。你能分享一些你的經驗嗎?謝謝!何時使用SafeArrayAccessData來鎖定SAFEARRAY

STDMETHODIMP Base::Method1(VARIANT values, VARIANT_BOOL result) 
{ 
    CComSafeArray<BSTR> ids; 
    ids.Attach(values.parray); 

    unsigned int size = ids.GetCount(); 
    for(unsigned int i = 0; i < size; ++i) 
    { 
    // use ids[i] here 
    } 
    // ... 
} 

回答

4

嗯,總是:)你需要它來獲得對數組內容的引用。

但是你使用了一個友好的C++包裝類。 CComSafeArray <>模板已經爲你做了這個,所以你不應該幫忙。它在Attach()方法中使用SafeArrayLock(),它還返回一個指向數組內容的指針,如SafeArrayAccessData()所做的。並使用它的析構函數自動解鎖,它在您的方法結束時運行。否則,鎖定可確保數組訪問是線程安全的,並且在訪問時無法刪除。在現有的代碼中沒有什麼危險,但這恰好符合自動化的安全性較好的原則。

+0

謝謝!你說,我的代碼比使用SafeArrayAccessData沒有什麼危險。你的意思是後者是線程安全的實現? – Archer

+0

我還有一個問題?作爲自動化的綠色之手,我想知道當我將這個數組從管理代碼傳遞給本地時,發生了什麼?誰分配了VARIANT正式參數的內存,誰複製了數據,誰釋放了它?你也可以提示一下嗎?謝謝! – Archer

+0

CLR的職責是將陣列編組爲SAFEARRAY。它存儲在COM互操作堆(CoTaskMemAlloc)中。它會在調用之後銷燬數組,所以如果要保留它,您需要複製數組數據。不知道如果你保持鎖定會發生什麼,我認爲會僵局。 –