【问题标题】:Is a COM object a C++ class?COM 对象是 C++ 类吗?
【发布时间】:2012-10-02 20:52:18
【问题描述】:

我读过两篇将 COM 对象描述为基本上 C++ 类的文章。这是真的?这是我正在阅读的一篇文章:http://www.codeproject.com/Articles/13601/COM-in-plain-C

它描述了一种在 C 中创建 COM 对象的方法。COM 强制该结构的第一个成员是某些函数指针。

我没有看到 COM 对象和 C++ 之间的具体关联,虽然我可以理解这种关系很容易理解。

【问题讨论】:

  • 一句话;不,任何曾经有幸在本机 C 中编写 COM 对象的人都会证明这一点。由于 vtable 布局,C++ 使得编写 COM 对象非常 更容易,但您不需要 C++ 来编写它们。事实上,您甚至不需要 C,因为 VB 和 C# 工程师会很高兴地承认这一点。
  • The layout of a COM object 文章解释的很好。
  • @JesseGood 很好的发现。唤起回忆的男人。

标签: c++ c com


【解决方案1】:

COM 明确指定其对象的布局方式:将虚函数表指针(又名 vtable 指针)作为对象中的第一个成员。它的设计使得布局与 Microsoft 编译器对 C++ 对象的布局方式相同,因此您可以拥有一个与手动定义的 C 结构进行相同编译的 C++ 类。

只要您使用的是 Microsoft 编译器,那么是的,COM 对象基本上就是一个 C++ 类实例。但是,如果您使用不同的编译器,则需要特别注意确保它以相同的方式布置 C++ 对象。只要您不使用多重继承或虚拟继承,大多数编译器都会将 vtable 放在首位,因此它通常可以工作,但有些编译器会将 vtable 放在最后。请务必阅读编译器的文档并确定它是否与 COM 兼容。

【讨论】:

    【解决方案2】:

    IMO,这在一定程度上取决于您如何定义 COM 对象。如果 COM 对象是与 COM 二进制接口兼容的任何对象,那么该对象是否在 C++ 内部实现是一个实现细节。可以用C++实现,也可以用其他各种方式实现,基本上没关系,只要通过COM接口访问即可。

    话虽如此,正如 Adam 和 WhozCraig 所指出的,COM 的二进制接口在设计时考虑了 MSVC 的 C++ 编译器。在 MSVC C++ 中编写 COM 对象是创建 COM 对象的“原始”方式。所以这两者肯定有着交织的历史,而且确实 COM 二进制接口规范与 MSVC 如何布置 C++ 对象有很多共同之处。但是,MSVC 编译器仍然必须生成 COM 绑定作为“额外”编译步骤(例如,COM 类型库和 C++ 导入头文件,以便其他 C++ 项目可以导入 COM 库)。

    【讨论】:

      【解决方案3】:

      COM 对象规范旨在利用 C++ 对象的现有二进制布局,因此从这个意义上说,它们基于 C++ 类。

      创建 IDispatch 接口是为了更轻松地从无法使用 C++ 虚拟表的语言中使用 COM。它为 COM 调用添加了额外的间接层。

      【讨论】:

        【解决方案4】:

        COM 代表组件对象模型。它是使用由类 ID (CLSID) 标识的不同类型的组件构建的库,这些组件是全局唯一标识符 (GUID)。每个 COM 组件都通过一个或多个接口公开其功能。组件支持的不同接口使用接口 ID (IID) 来区分,IID 也是 GUID。

        【讨论】:

          【解决方案5】:

          添加另一个答案,因为我认为有一些关于 COM 和 C++ 的非常有用的知识需要了解,而其他答案没有涵盖。

          也许要得到三件重要的东西:

            1234563这些接口中的一个是您在 QI for IUnknown(又称“规范未知”)时返回的接口)。
          • COM 接口恰好与 MSVC 和所有 (AFAIK) Windows 编译器实现的 C++ 对象的 vtable 具有相同的布局。

          • COM 更侧重于接口。 C++ 更侧重于类。

          第二个是使在 C++ 中实现 COM 对象变得简单的原因。但其中的第一个意味着主题有很多变化。所以你可以:

          • 在 C++ 中作为实现一个接口的类实现的单接口 COM 对象

          • 具有多个接口的单个​​ COM 对象,使用 C++ 的多重继承实现为实现多个接口的 C++ 类。

          • 具有多个接口的单个​​ COM 对象,实现了协作 C++ 对象实例的集合,每个 COM 接口可能有一个 C++ 类;或者一个 C++ 类实现了 COM 对象的大部分接口,并使用辅助 C++ 类来实现不常用的接口,也许只在需要时动态创建这些辅助 C++ 类! (请注意,这又与 COM 聚合分开。)

          最后一种情况特别有趣,因为它说明了单个 COM 对象可以映射到实现中的多个 C++ 对象。 COM 不关心,只要你遵守它的规则(特别是关于引用计数,QI 应该是关联的、自反的和传递的,所有的 COM 对象都应该有一个 Canonical IUnknown。)

          尽管在 C++ 中实现 COM 对象相当简单,但您不能假设您所掌握的任何 COM 对象实际上都是幕后的 C++ 类:它可以在 C、汇编程序中实现,或者是一段动态生成的代码,它是一些 C# 代码的包装器。

          请记住,RTTI 和 C++ 异常等 C++ 功能不是 COM 的一部分,因此您不能对任意 COM 对象使用它们 - 当然,除非您知道它实际上是您自己的 C++ 类之一,其中如果您确实将对象用作 C++ 类,而不是 COM 对象。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-11-10
            • 2013-02-02
            • 2011-08-11
            • 1970-01-01
            • 1970-01-01
            • 2014-09-01
            • 2012-01-17
            相关资源
            最近更新 更多