2011-07-03 30 views
7

查看由CCW創建的生成的TLB文件雖然OLE/COM對象查看器顯示IID保持不變,除非我改變接口的設計(這是正確的行爲),我擔心的是如果我在另一個編譯相同的代碼機器將會生成一個完全不同的IID,儘管接口沒有改變,從而破壞了現有的COM客戶端。.NET COM Callable Wrapper如何生成IID?

  1. COM Callable Wrapper如何生成COM接口ID?
  2. CCW如何知道接口是否已更改並需要生成新的IID?
  3. 只需要生成我自己的文件並在源文件中聲明,會更安全嗎?

回答

4

一個類型的guid並不特定於COM interop,所有的.NET類型都有一個guid。您可以從Type.GUID屬性中獲取它。 CLR中的代碼可以從SSCLI20發行版中獲得。您可以通過檢查clr/scr/vm/methodtable.cpp中的代碼,MethodTable :: GetGuid()方法來查看算法。

總結的算法:

  • 如果類型具有[的Guid]屬性,則返回該
  • 如果類型是一個接口類型,那麼生成所述接口類型定義的stringized版本。這由interoputil.cpp中的GetStringizedItfDef()完成。它從完全限定類型名稱開始,並追加每個成員定義的字符串版本。
  • 對於所有其他類型,生成類的字符串版本。它從完全限定類型名稱開始,附加類名稱並附加完全限定程序集名稱。
  • 然後通過輔助函數CorGuidFromNameW()將得到的字符串散列成Guid。

這是足夠的信息來回答你的問題:

如何通過COM可調用包裝產生的COM接口ID?

它使用上面的算法生成的Type.GUID。算法中的元素沒有特定於執行的機器,因此您不必擔心在不同的生成機器上獲取不同的IID和CLSID。

CCW如何知道接口是否已更改並需要生成新的IID?

它沒有。它純粹依賴於爲不同接口定義生成不同GUID的算法。

在源文件中生成我自己的文件並聲明它會更安全嗎?

不是。這種算法沒有文檔化的失敗模式。使用自己的[Guid]屬性顯着增加了在必要時忘記更改它的機率。這是一個經常採用的捷徑,也是DLL Hell的主要來源。這種令人討厭的類型使客戶端崩潰幾乎無法診斷硬件異常。與E_NOINTERFACE這個仍然很難但不可能的類型相反。通過依賴自動生成的Guid,實際上只有兩個缺點:當你忘記在重建它們之前註銷程序集時,它往往會導致註冊表污染你的開發機器。當你解決COM錯誤時,它會讓你稍微放慢一點,因爲你不知道這些GUID。無可否認,註冊表污染對我來說是足夠好的理由。