接口指针和接口

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

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

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

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

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

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

COM 对象和接口