3

我试图了解 COM 如何指定其对象的布局,以便想要使用 COM 对象的客户端知道如何去做。

我读过一个实现多个接口的 COM 对象可以通过不同的方式来实现它,包括使用嵌套类或多重继承。

我的理解是,这两种技术都必须产生相同的内存布局(符合 COM 规范),以便想要使用 COM 对象(例如在 C 中)的客户端知道如何去做。

所以我的具体问题是:使用多重继承与嵌套类实现的 c++ 对象的内存布局是否存在差异。

有人可以指出指定 COM 对象布局的位置吗?

4

4 回答 4

8

COM 完全不知道对象的内存布局。当它调用时,它想要和需要的只是一个函数指针表IUnknown::QueryInterface()。如何实现它完全取决于您。MFC 使用嵌套类,几乎所有其他东西都利用了 C++ 编译器中对多重继承的内置支持。MSVC++ 编译器实现它的方式与 COM 需要的完全兼容。这绝非偶然。使用您在有关 COM 的书籍中看到的样板代码,这些代码展示了如何正确实现 IUnknown。

于 2011-01-05T21:20:39.597 回答
5

COM 中指定的唯一“布局”是与每个接口关联的 vtable(虚拟函数指针表)。每个接口都派生自 IUnknown,因此无论客户有一个指针指向的对象接口,他都可以调用 QueryInterface 来获取同一对象上的不同接口。

对象没有强制布局。事实上,COM 中的对象的整个概念与 OO 语言中的类实例非常不同:知道两个接口是否由同一个 COM 对象公开的唯一方法是为它们的 IUnknown 接口调用 QueryInterface -当且仅当它们返回相同的接口指针时,它们才是同一个对象的接口。

这是一个非常灵活的想法:

  • it is possible, for example, to have COM objects with only part of their internal state loaded into memory: other parts of their state may be lazy loaded/allocated as further interfaces are requested.
  • A COM object's state may be spread across several non-contiguous memory regions.
于 2011-01-05T21:31:14.460 回答
1

我不相信单个COM接口可以有多重继承,但是一个类可以通过多重继承实现多个接口。所以多重继承布局是无关紧要的——每个接口都有一个唯一的布局,由编译器提供一个指向正确布局的指针。

对于单继承,编译器会将父类定义放在最前面,然后是子类。这是由数据元素的标准定义的,但这又是无关紧要的,因为接口没有数据。该标准没有说明 vtables 的存在或布局,但要使多态性工作,它必须以相同的方式布局 - 首先是父级,其次是子级。

如果你通过多重继承来实现多个接口,你会发现一个令人惊讶的事实。当您将指向您的类对象的指针从一个接口转换到另一个接口时,地址将会改变!这是因为不同的接口(vtables)必须匹配接口声明,所以必须有不同的布局。这些布局都包含在同一个对象中,但是编译器在转换时会进行指针操作以将其转换为正确的子集。

于 2011-01-05T20:57:33.980 回答
0

如果混合中涉及虚函数,特别是如果最派生类添加了它自己的任何一个,那么两种方法的内存布局将有所不同。

于 2011-01-05T20:48:08.243 回答