2015-07-10 49 views
3

如果我調用在一個線程上返回BSTR的COM方法,可以安全地從另一個線程調用BSTR上的SysFreeString()?一旦COM調用完成,我將不再使用第一個線程上的BSTR,所以不應該有任何併發​​問題。然而,考慮到COM是如何與線程相關的,我不確定SysFreeString()是否依賴BSTR被分配到同一個線程上。在不同的線程上釋放BSTR是否安全?

示例代碼:

BSTR value = nullptr; 
HRESULT hr = pComObject->DoSomething(&value); 
if(FAILED(hr)) 
{ 
    return hr; 
} 

std::thread t([value] { 
    // do something with value 
    SysFreeString(value); 
}); 
t.detach(); 

回答

3

MSDN並不表示它明確,但仍有引用Sys*String功能使用的IMalloc OS實現,通過CoGetMalloc和朋友。

自動化可能會緩存分配給BSTR的空間。這加快了SysAllocString/SysFreeString序列的速度。但是,這也可能導致IMallocSpy將泄漏分配給錯誤的內存用戶,因爲它不知道自動化完成的緩存。

COM實現is thread safe

一般情況下,你不應該執行IMalloc,而不是使用COM實現,這是保證線程安全的管理任務內存。通過調用CoGetMalloc函數,您可以獲得COM任務分配器對象的IMalloc指針。

總而言之,從另一個線程中釋放字符串是可以的。

+0

BSTR是專門爲此任務設計的。在不同線程上調用SysAllocString和SysFreeString通常在分佈式COM服務器中執行。實際上,如果函數返回一個[out] BSTR **參數的字符串,則會在編組之後分配並重新分配本地副本。 – Bart

+0

事實上,來自編組的BSTRs很可能也會被分配到同一個線程中,而這部分/引用並不能解釋在線程之間傳遞BSTR是否正確。我很確定這個API是完全線程安全的,否則會導致大量的問題。 MSDN應該剛剛提到它很清楚,API是線程安全的,並且指針可以在線程之間傳輸而不受限制。 –

+0

就我的記憶來說,Don Box在他的書「Essential COM」中解釋了這一點, – Bart