2010-08-29 30 views
2

我基於VC++ 2005對話框的應用程序初始化對話框類中的COM對象,並在工作線程中使用它。VC++線程編組和COM:該應用程序稱爲一個接口,被編組爲一個不同的線程

我叫CoInitialize(NULL)在應用程序的開始和工作線程的開始。但是,當一個COM方法被稱爲錯誤「該應用程序稱爲一個不同的線程編組的接口」如下。

如果我使用的CoInitializeEx(0,COINIT_MULTITHREADED),那麼我會得到相同的錯誤消息

請幫我找到病根。

謝謝。

回答

3

您通過調用CoInitialize(NULL)創建了兩個單線程單元。在可用之前,接口指針必須從一個公寓編組到另一個公寓。初始化工作線程作爲MTA不能解決問題。原始接口指針仍然在單線程的公寓中創建,因此不是線程安全的。換句話說,你不能直接從線程調用接口方法。這些調用必須封送到創建接口的線程。對接口指針進行封裝可以建立一個可能的管道。

你唯一不需要編組的時候是兩個線程都是MTA。這幾乎是不可能的,你的主線程必須是STA,如果它創建任何窗口。而COM服務器實際上必須是線程安全的,他們很少。他們通過註冊表中的ThreadingModel鍵宣告他們需要什麼。如果有必要,COM實際上會創建一個STA線程,以便爲服務器找到一個好的主頁。

您必須用CoMarshalInterThreadInterfaceInStream()封送指針以避免該錯誤。這是一個相當不友好的功能,IGlobalInterfaceTable更易於使用。 COM服務器也必須支持它,你通常需要一個代理/存根DLL來處理編組。如果沒有,你會得到E_NOINTERFACE。

還要注意開銷,將工作線程調用到主線程的調用非常昂貴,並且受到主線程響應的影響。換句話說,如果你編寫線程來加速程序或避免阻塞用戶界面,那麼這實際上不會工作。這是'沒有免費午餐'的原則。

0

您是否在兩個地方的主應用和線程切換到CoInitializeEx?如果沒有,那麼嘗試這種配置。如果您可以發佈一些源代碼以更好地描述問題,這將會很有用。無論如何,這裏是一篇很好的文章,可以幫助您瞭解COM中的公寓http://msdn.microsoft.com/en-us/library/ms809971.aspx

1

我想在另一個線程中訪問COM對象的方法之一就是使用全局接口指針。初始化後,將GIT指針與dwCookie值一起構成線程。然後在線程內重新解釋指針爲DWORD並將其傳遞給GI表以獲取我們的COM指針。

謝謝

相關問題