【问题标题】:How does the .NET COM Callable Wrapper generate IIDs?.NET COM 可调用包装器如何生成 IID?
【发布时间】:2011-07-04 02:31:48
【问题描述】:

查看由 CCW 创建的生成的 TLB 文件,尽管 OLE/COM 对象查看器显示 IID 保持不变,除非我更改接口的设计(这是正确的行为),我担心的是,如果我在尽管接口没有改变并因此破坏现有的 COM 客户端,但仍会生成另一台机器完全不同的 IID。

  1. COM 可调用包装器如何生成 COM 接口 ID?
  2. CCW 如何知道接口是否已更改并需要生成新的 IID?
  3. 只生成我自己的并在源文件中声明会更安全吗?

【问题讨论】:

    标签: .net c++-cli ccw


    【解决方案1】:

    类型的 guid 并不特定于 COM 互操作,所有 .NET 类型都有一个 guid。您可以从 Type.GUID 属性中获取它。生成它的 CLR 中的代码可从 SSCLI20 发行版中获得。您可以通过查看 clr/scr/vm/methodtable.cpp 中的代码,MethodTable::GetGuid() 方法来查看算法。

    算法总结:

    • 如果类型具有 [Guid] 属性,则返回该属性
    • 如果类型是接口类型,则生成接口类型定义的字符串化版本。这是由 interoputil.cpp 中的 GetStringizedItfDef() 完成的。它以完全限定的类型名称开头,并附加每个成员定义的字符串版本。
    • 对于所有其他类型,生成该类的字符串化版本。它以完全限定的类型名称开头,附加类名称并附加完全限定的程序集名称。
    • 然后通过辅助函数 CorGuidFromNameW() 将生成的字符串散列到 Guid 中。

    这些信息足以回答您的问题:

    COM 可调用包装器如何生成 COM 接口 ID?

    它使用上述算法生成的 Type.GUID。算法中的任何元素都不是特定于执行它的机器,因此您不必担心在不同的构建机器上获得不同的 IID 和 CLSID。

    CCW如何知道接口是否发生了变化并需要生成新的IID?

    它没有。它完全依赖于为不同接口定义生成不同 GUID 的算法。

    只生成我自己的并在源文件中声明会更安全吗?

    不是真的。该算法没有记录在案的故障模式。使用您自己的 [Guid] 属性会显着增加您在必要时忘记更改它的几率。这是一个经常使用的快捷方式,也是 DLL Hell 的主要来源。讨厌的那种,使客户端崩溃几乎不可能诊断出硬件异常的那种。与仍然很难但并非不可能的 E_NOINTERFACE 不同。依靠自动生成的 Guid,我只能想到两个缺点:当您忘记在重建程序集之前取消注册程序集时,它往往会在您的开发机器上造成注册表污染。当您对 COM 错误进行故障排除时,它会减慢您的速度,因为您并不容易了解 guid。诚然,注册表污染对我来说已经足够了。

    【讨论】:

    • “使用您自己的 [Guid] 属性会显着增加您在必要时忘记更改它的几率。”为什么我必须更改生成的 GUID?
    • 如果我使用自动生成的 GUID,它会如何污染注册表?它不应该只是在同一个地方覆盖注册表吗?
    • 还有一个“注册 COM 互操作”选项,据说可以为我“取消注册”以防止污染。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 2015-07-24
    相关资源
    最近更新 更多