2009-09-26 149 views
0

我有一段.NET代碼,由於各種原因(可靠性,部署)必須在單獨的AppDomain中運行。我創建了一個派生自MBR的代理對象,它將調用委託給實際的東西,所以它不會加載到當前的AppDomain中。我通過通常的CreateInstanceAndUnwrap創建代理。從COM互操作失敗使用AppDomain

this.eDirectCommunication = (EDirectCommunicationProxy) this.appDomain.CreateInstanceAndUnwrap(x, y); 

這個偉大的工程,當我使用它從一個.NET客戶端,從COM客戶端轉換失敗加載然而,當。我無法從透明代理投射。我驗證了需要的類型是在所需的AppDomain上創建的,並且Unwrap成功,只是轉換失敗。有趣的是,它在兩個AppDomain具有相同的基本目錄時工作,這指向程序集綁定失敗。但Fusion日誌查看器沒有提到任何問題。

有兩個有點類似的問題herehere,但他們沒有提供答案。 任何想法出了什麼問題,或者我該如何進一步調試?

回答

1

幾年前我遇到了這個確切的問題。 IIRC,問題在於調用堆棧跨越兩個appdomain邊界,這導致代理到被管對象被編組兩次(COM-> default-> yours:new object: - > yours-> default)。通常不是問題,但有一個特殊的接口,.NET COM封送器QI爲此說「嗨,我是一個託管對象,需要特殊的編組行爲」(對不起,不記得IID-嘗試ComTrace或將您的自己的IDispatch impl並通過CLR編組來查看)。當你在默認域中運行時,它會知道你被管理,然後請求並嘗試加載你的託管類型,只有當你的新域的basedir與默認相同時,它纔會成功。這顯然打敗了整個目的。

我已經處理了幾種方法。一種方法是將對象創建爲異步,以便我可以將託管代理直接推送到新域中的非託管代碼(例如,註冊非託管回調,並直接從新域調用它,繞過默認域)。這在添加場景中顯然非常棘手,您無法控制端到端的所有內容。

另一個是有一小塊非託管代碼,當.NET平臺處理器問「你真的是一個託管對象嗎?但是會通過所有其他QIs以及IDispatch上的所有內容而不受干擾(我僅限於使用IDispatch,這使得它更容易)。所以新的序列變爲:COM-> default-> yours:new object-> new proxy wrapper-> default-> COM。

主要PITA-我在CLR互操作團隊中發現了一篇博客文章,該文章在未來的CLR發佈中爲此懸浮了一些可能的修復方法,但這是幾年前的事,我不記得是誰(對不起,我不再爲了生活而互助了,謝天謝地!)