第3章 QueryInterface函数

 
第3章 QueryInterface函数

1、接口查询:

客户同组件的交互都是通过一个接口完成的。在客户查询组件的其他接口时,也是通过接口完成的。这个接口就是IUnknown。

IUnknown接口的定义包含在Win32 SDK中的UNKNOWN.H头文件中。

interface IUnknown

{

    virtual HRESULT _stdcall QueryInterface(const IID& iid,void **ppv) = 0;

    virtual ULONG _stdcall AddRef() = 0;

    virtual ULONG _stdcall Release() = 0;

}

在IUnknown中定义了一个名为QueryInterface的函数。客户可以调用QueryInterface来决定组件是否支持某个特定的接口。

IUnknown指针的获取:IUnknown* GreateInstance();

2、所有的COM接口都需要继承IUnknown。

3、由于所有的COM接口都继承了IUnknown,每个接口的vtbl中的前三个函数都是QueryInterface,AddRef和Release。若某个接口的vtbl中的前三个函数不是这三个,那么它将不是一个COM接口。由于所有的接口都是从IUnknown 继承的,因此所有的接口都支持QueryInterface.因此组件的任何一个接口都可以被客户用来获取它所支持的其他接口。

4、非虚拟继承:注意IUnknown并不是虚拟基类,所以COM接口并不能按虚拟方式继承IUnknown,这是由于会导致与COM不兼容的vtbl。若COM接口按虚拟方式继承IUnknown,那么COM接口的vtbl中的头三个函数指向的将不是IUnknown的三个成员函数。

因为虚拟继承是与编译器相关的,如微软的Visual C++是通过在每个带有虚基类的类的实例中增加一个隐藏的vbptr(虚基类指针)域来实现这个技术的。这个指针指向一个共享的、每个虚基类占一项的表,表中是vbptr域的地址指针到类中虚基类的偏移量。其它的一些实现采用了在继承类中指向其虚基类的内嵌指针,为每个虚基类分配一个指针。这种描述方式可以以更少的代码来定位虚基类,但是现今代码优化器常常可以消除对访问虚基类的重复计算。它的不利之处则是如果有多个虚基类的话,其类的实例大小将会变得比较大,而且对于虚基类的虚基类的访问会很慢(除非再引入更多的隐藏指针~~),当引用成员时也需要更多的指针。是在类中间添加隐藏的额外变量来实现虚继承的。这和COM接口规范有冲突,不符合二进制标准,COM接口不允许有成员变量的。所以在COM中所有的其他接口都是直接从IUnknown接口继承,结果就是每个接口的vbtl的前三个函数都是IUnknown接口里的三个函数。

5、一个QuertyInterface可以用一个简单的if-then-else语句实现,但case语句是无法用的,因为接口标识符是一个结构而不是一个数。

6、多重类型及类型转换

7、QueryInterface的规则

(1)QueryInterface返回的总是同一IUnknown指针。

(2)若客户曾经获取过某个接口,那么它将总能获取此接口。

(3)客户可以再次获取已经拥有的接口。

(4)客户可以从任何接口返回到起始接口。

(5)若能够从某个借口获取某特定接口,那么可以从任意接口都将可以获取此接口。

8、IID(Interface Index):接口标识符。接口的IID决定了它的版本。当改变了下列条件中的任何一个时,就应给新接口指定新的ID:

(1)接口中函数的数目。

(2)接口中函数的是顺序。

(3)某个函数的参数。

(4)某个函数参数的顺序。

(5)某个函数参数的类型。

(6)函数可能的返回值。

(7)函数参数的含义。

(8)接口中函数的含义。

9、避免违反隐含和约:

(1)使接口不论在其成员函数怎么被调用都能正常工作。

(2)强制客户按一定的方式来使用此接口并在文档中将这一点说明清楚。

10、QueryInstance实现及使用的完整例子源码:CSDN我的资源中InsideCOM\CHAP03。

 

你可能感兴趣的:(优化,工作,文档,interface,微软,编译器)