【发布时间】:2011-07-04 02:31:48
【问题描述】:
查看由 CCW 创建的生成的 TLB 文件,尽管 OLE/COM 对象查看器显示 IID 保持不变,除非我更改接口的设计(这是正确的行为),我担心的是,如果我在尽管接口没有改变并因此破坏现有的 COM 客户端,但仍会生成另一台机器完全不同的 IID。
- COM 可调用包装器如何生成 COM 接口 ID?
- CCW 如何知道接口是否已更改并需要生成新的 IID?
- 只生成我自己的并在源文件中声明会更安全吗?
【问题讨论】:
查看由 CCW 创建的生成的 TLB 文件,尽管 OLE/COM 对象查看器显示 IID 保持不变,除非我更改接口的设计(这是正确的行为),我担心的是,如果我在尽管接口没有改变并因此破坏现有的 COM 客户端,但仍会生成另一台机器完全不同的 IID。
【问题讨论】:
类型的 guid 并不特定于 COM 互操作,所有 .NET 类型都有一个 guid。您可以从 Type.GUID 属性中获取它。生成它的 CLR 中的代码可从 SSCLI20 发行版中获得。您可以通过查看 clr/scr/vm/methodtable.cpp 中的代码,MethodTable::GetGuid() 方法来查看算法。
算法总结:
这些信息足以回答您的问题:
COM 可调用包装器如何生成 COM 接口 ID?
它使用上述算法生成的 Type.GUID。算法中的任何元素都不是特定于执行它的机器,因此您不必担心在不同的构建机器上获得不同的 IID 和 CLSID。
CCW如何知道接口是否发生了变化并需要生成新的IID?
它没有。它完全依赖于为不同接口定义生成不同 GUID 的算法。
只生成我自己的并在源文件中声明会更安全吗?
不是真的。该算法没有记录在案的故障模式。使用您自己的 [Guid] 属性会显着增加您在必要时忘记更改它的几率。这是一个经常使用的快捷方式,也是 DLL Hell 的主要来源。讨厌的那种,使客户端崩溃几乎不可能诊断出硬件异常的那种。与仍然很难但并非不可能的 E_NOINTERFACE 不同。依靠自动生成的 Guid,我只能想到两个缺点:当您忘记在重建程序集之前取消注册程序集时,它往往会在您的开发机器上造成注册表污染。当您对 COM 错误进行故障排除时,它会减慢您的速度,因为您并不容易了解 guid。诚然,注册表污染对我来说已经足够了。
【讨论】: