接口指针和接口

接口实现的实例实际上是指向方法指针数组的指针(即一个引用接口中指定的所有方法的实现的函数表)。 具有多个接口的对象可以提供指向多个函数表的指针。 具有可访问数组的指针的任何代码可调用该接口中的方法。

确切地说,这种多重间接性并不方便,因此,指向另一个对象必须调用其方法的接口函数表的指针简称接口指针。 可以在 C 应用程序中手动创建函数表,也可以使用 Visual C++(或支持 COM 的其他面向对象的语言)几乎自动创建函数表。

借助适当的编译器支持(C 和 C++ 中固有),客户端可以通过名称(而不是数组中的位置)调用接口方法。 由于接口是一种类型,因此编译器(指定方法的名称)可以检查每个接口方法调用的参数类型和返回值。 相比之下,如果客户端使用基于位置的调用方案,则此类类型检查不可用,即使在 C 或 C++ 中也是如此。

每个接口都是一组方法函数的不可变协定。 在运行时使用全局唯一接口标识符 (IID) 引用接口。 此 IID 是 COM 支持的全局唯一标识符 (GUID) 的特定实例,允许客户端准确询问对象是否支持接口的语义,而无需不必要的开销,并且系统中不会因为有多个版本采用相同名称的同一接口而发生混淆。

总之,必须了解 COM 接口是什么,它不是:

  • COM 接口与 C++ 类不同。 纯虚拟定义没有实现。 C++ 程序员可以将接口实现定义为类,但这属于实现详细信息的标题,COM 不会指定。 必须为实际存在的接口创建实现接口的对象实例。 此外,只要行为符合接口定义,不同的对象类可能以不同方式实现接口,但以二进制形式互换使用。
  • COM 接口不是对象。 它只是一组相关的函数,是客户端和对象通信的二进制标准。 只要它可以提供指向接口方法的指针,就可以使用任何内部状态表示形式以任何语言实现对象。
  • COM 接口是强类型。 每个接口都有自己的接口标识符 (GUID),从而消除任何其他命名方案发生重复的可能性。
  • COM 接口不可变。 不能定义旧接口的新版本,并为其提供相同的标识符。 添加或删除接口的方法或更改语义会创建新的接口,而不是旧接口的新版本。 因此,新接口不会与旧接口相冲突。 但是,对象可以同时支持多个接口,并且可以公开具有不同标识符的接口的连续修订版本。 因此,每个接口都是一个单独的协定,系统范围的对象不需要关注所调用的接口版本是否期望的版本。 接口 ID (IID) 显式且唯一地定义接口协定。

COM 对象和接口