注意:
问题:
插图:
IS8Simulation *pis8 = NULL;
...
CoCreateInstance(
clsid,
NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IS8Simulation),
(void **) &pis8);
...
hThread = CreateThread(
NULL,
0,
SecondaryThread,
//interface pointer pis8
0,
&dwGenericThreadID);
...
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
//using iValue accordingly
//E.g.: iValue->Open
此致
答案 0 :(得分:8)
如下所述,在不安全的线程之间传递COM
接口指针。
假设你知道自己在做什么:
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) pis8
0,
&dwGenericThreadID);
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
((IS8Simulation*) iValue)->Open();
}
线程安全版本:
void MainThread()
{
IStream* psis8;
HRESULT res = CoMarshalInterThreadInterfaceInStream (IID_IS8SIMULATION, pis8, &psis8);
if (FAILED(res))
return;
hThread = CreateThread(
NULL,
0,
SecondaryThread,
(LPVOID) psis8
0,
&dwGenericThreadID
);
}
DWORD WINAPI SecondaryThread(LPVOID iValue)
{
IS8Simulation* pis8;
HRESULT res = CoGetInterfaceAndReleaseStream((IStream*) iValue, IID_IS8SIMULATION, &pis8);
if (FAILED(res))
return (DWORD) res;
pis8->Open();
}
答案 1 :(得分:7)
如果你问题中的接口是COM接口,Quassnoi给出的方法可能还不够。您必须注意正在使用的COM对象的线程模型。如果辅助线程将从创建COM对象的COM公寓加入单独的COM公寓,并且该对象不是 apartment-agile ,则需要封送该接口指针,以便辅助线程获取代理,而不是指向该对象的直接指针。
通过使用IMarshal的特殊实现,COM对象通常是公寓敏捷的。最简单的方法是聚合Free Threaded Marshaler。
一些有用的链接......
更新:关于自由线程的Marshaler ......
从这个主题的评论中可以清楚地看到,有些人会建议你永远不要触摸FTM。虽然“有效COM”是一本很好的书,但我认为它的一些建议可以解释。第33项说“小心FTM”;它没有说“永远不要使用FTM”。非常明智地,它建议谨慎,特别是当您的公寓敏捷对象持有对其他对象的引用时,因为它们可能不是公寓敏捷的。所以真正的建议是:在构建公寓敏捷对象时要慎重考虑,无论他们是否使用FTM来实现敏捷性。如果您确定可以构建一个敏捷的公寓对象,我认为没有理由不使用FTM来实现这一目标。
答案 2 :(得分:2)
您基本上需要执行以下操作:
CoMashalInterThreadInterfaceInStream
==>你得到一个IStream接口。 CoGetInterfaceAndReleaseStream
以获取接口(或必要时的代理)。 除非创建线程失败,否则不要释放IStream接口,并且在yu调用CoGetInterfaceAndReleaseStream
之前不要退出线程。
COM运行时将自动为您创建代理。代理确保例如在创建它的线程上调用一个单元线程的COM组件。但是,这也需要: