2011-11-22 916 views

回答

0

您尚未爲您的COM對象註冊代理/存根對象,因此其接口無法編組到相關線程中。你有兩種選擇 a)註冊代理。如果接口對您的應用程序是私人的,您可以合併代理存根。如果他們不是你應該創建一個單獨的DLL。 ATL嚮導可以幫助您生成代理,所以很可能您已經擁有它們,而您只是沒有安裝/註冊它們。

代理將確保對您的對象的調用發生在它所註冊的同一COM套件中。在你的情況下,STA。這也減少了鎖定的需要 - 因爲一次只能在您的代碼中進行一次調用。 http://msdn.microsoft.com/en-us/library/ms809971.aspx

當然,您仍然需要防止重入,因爲您的STA對象可能會在其呼出期間重新進入。 http://blogs.msdn.com/b/cbrumme/archive/2004/02/02/66219.aspx

使用代理的缺點是在編組和等待STA時都存在性能成本。

在經典的Win32模型中,您應該始終使用STA封裝UI的COM對象,因爲HWND始終綁定到單個線程。 b)聚合自由線程編組器。 你也可以在ATL中找到這個選項。自由線程編組器使您的COM對象可以直接從過程中的任何公寓調用。 http://msdn.microsoft.com/en-us/library/windows/desktop/ms694500(v=vs.85).aspx

當您使用FTM時,您的對象上的調用是直接的vtable調用 - 不涉及marshalliong。

選擇此選項需要您使代碼成爲線程安全的(通過應用適當的鎖定),因爲調用現在可以同時從多個線程進來。

另一個負擔是FTM對象不能直接保存到接口指針上,除非它確實知道那些對象也會聚合FTM。所以當你從其他人處獲得一個IUnknown時,你需要將它存儲在一個公寓中性格式中(比如在全局接口表中)。

由於這個和其他原因,FTM對於瞭解他們在做什麼的人來說是一個高級選擇。但它也是非UI代碼的最高性能選項。

Martyn

相關問題