Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading VC++;线程封送和COM:应用程序调用为不同线程封送的接口_Multithreading_Visual C++_Com - Fatal编程技术网

Multithreading VC++;线程封送和COM:应用程序调用为不同线程封送的接口

Multithreading VC++;线程封送和COM:应用程序调用为不同线程封送的接口,multithreading,visual-c++,com,Multithreading,Visual C++,Com,我的VC++2005基于对话框的应用程序初始化对话框类中的COM对象,并在工作线程中使用它 我在应用程序开始时调用了CoInitialize(NULL),在工作线程开始时调用了。但是当调用COM方法时,错误“应用程序调用了为不同线程封送的接口”如下 如果我使用coinitializex(0,COINIT_多线程),那么我将得到相同的错误消息 请帮我找出根本原因 谢谢。这可能是最简单的方法 看。您可以下载代码示例并在Client.cpp中找到不同的需求实现。您通过调用CoInitialize(NU

我的VC++2005基于对话框的应用程序初始化对话框类中的COM对象,并在工作线程中使用它

我在应用程序开始时调用了CoInitialize(NULL),在工作线程开始时调用了。但是当调用COM方法时,错误“应用程序调用了为不同线程封送的接口”如下

如果我使用coinitializex(0,COINIT_多线程),那么我将得到相同的错误消息

请帮我找出根本原因

谢谢。

这可能是最简单的方法


看。您可以下载代码示例并在Client.cpp中找到不同的需求实现。

您通过调用CoInitialize(NULL)创建了两个单线程单元。接口指针在可用之前必须从一个单元封送到另一个单元。将工作线程初始化为MTA并不能解决此问题。原始接口指针仍然是在单线程单元中创建的,因此不是线程安全的。换句话说,您不能直接从线程调用接口方法。这些调用必须封送到创建接口的线程。封送接口指针将设置使之成为可能的管道

只有当两个线程都是MTA时,才不必封送。这几乎是不可能的,你的主线程必须是STA,如果它创建任何窗口。而COM服务器实际上必须是线程安全的,它们很少是线程安全的。他们在注册表中用ThreadingModel键公布所需内容。如果有必要,COM将实际创建一个STA线程,以便为服务器找到一个好的主页

必须使用CoMarshalInterThreadInterfaceInStream()封送指针以避免错误。这是一个相当不友好的函数,IGlobalInterfaceTable更容易使用。COM服务器也必须支持它,您通常需要一个代理/存根DLL来处理封送。如果没有的话,你就不会有机会了


还要注意开销,从工作线程到主线程的封送调用非常昂贵,并且取决于主线程的响应速度。换句话说,如果您编写线程是为了加速程序或避免阻塞用户界面,那么这实际上是行不通的。这是“没有免费午餐”的原则。

我认为在另一个线程中访问COM对象的方法之一是使用全局接口指针。初始化后,将GIT指针与dwCookie值一起形成线程。然后在线程内部重新解释将指针转换为DWORD,并将其传递给GI表以获取COM指针

谢谢