COM对象是C ++类吗?

时间:2012-10-12 04:31:30

标签: c++ c com

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

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

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

5 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

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库)。

答案 2 :(得分:2)

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

创建IDispatch接口是为了更容易地使用不能使用C ++ vtables的语言的COM。它为COM调用添加了额外的间接层。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

添加另一个答案,因为我认为有关COM和C ++的一些非常有用的事情,其他答案没有涵盖。

或许有三个重要的事情要做:

  • COM对象实际上是一个 COM接口集合,它们配合使用,可以看到具有共享COM对象标识的外观(您可以从任何接口到任何其他接口进行QI,并且这些接口是你在IUnknown QI时回来的,也就是'规范的未知'。

  • COM接口的布局与MSVC实现的C ++对象的vtable相同 - 以及所有(AFAIK)窗口编译器。

  • COM更专注于接口。 C ++更专注于类。

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

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

  • 具有多个接口的单个​​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对象。