在不同的线程上释放BSTR是否安全?

问题描述:

如果我调用在一个线程上返回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(); 

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