C++ COM编程之QueryInterface函数(一)
组件对外公布的是接口;一个组件可以实现多个接口,也就是说可以对外公布多个接口,之前也总结过了,你很少会100%的去完全了解一个组件的所有接口,就像你去学习编程一样,你几乎
前言
组件对外公布的是接口;一个组件可以实现多个接口,也就是说可以对外公布多个接口,之前也总结过了,你很少会100%的去完全了解一个组件的所有接口,就像你去学习编程一样,你几乎不可能去成为编程中的全才。那么,既然我们不能去完全的了解一个组件提供的所有接口,那么我们在实际开发中,如何去判断一个组件是否提供对应的接口呢?看文档?是的,是个好主意,在文档的海洋,找到一个知识点,真的很难,浪费时间和精力;其实,组件本身就提供对自己查询的一个接口,让客户去询问组件,问它是否支持某个接口,在经过多次的这种询问之后,客户对于组件的认识将越来越清晰;而我这篇文章和下一篇文章就是对这种询问机制进行详细的剖析和总结。
关于IUnknown
上面说到组件本身提供一个对自己查询的接口,那么这个接口是什么呢?这就是大名鼎鼎的IUnknown接口了,IUnknown接口在Windows SDK的unknwn.h中定义,它的定义如下:
既然,我们可以只用QueryInterface去询问组件是否支持某个接口,但是,这一切都是基于获得了IUnknown接口指针之后,才能进行的操作,那么如何获得一个指向组件的IUnknown接口指针呢?我们可以实现一个CreateInstance函数,它建立一个组件并返回一个IUnknown指针;对于客户来说,可以调用CreateInstance获得IUnknown指针,而不用使用new操作符了。在系统的总结了COM的所有基础知识之后,我再说说系统提供的一个创建组件实例的API函数。
关于QueryInterface
IUnknown中包含一个名为QueryInterface的成员函数,客户可以通过此函数来查询某个组件是否支持某个特定的接口。若支持,QueryInterface将返回一个指向此接口的指针;否则返回值将是一个错误代码;然后客户可以接着查询其它接口。
从QueryInterface函数的声明中可以看出,QueryInterface有两个参数,第一个参数标识客户所需的接口,这个参数是一个接口标识符(IID)结构,在之后的文章中,我会总结有关IID的知识的;第二个参数用来存放所请求的接口的地址。QueryInterface返回的是一个HRESULT值,它是一个具有特定结构的32位值,之后我也会进行总结的;对于返回的HRESULT值,在实际开发中,需要使用SUCCEEDED宏或FAILED宏去进行判断HRESULT值是表示成功还是失败。
QueryInterface的简单实现
总结了QueryInterface的简单实现,说白了,就是简单工厂模式的实现;上面也说了,就是根据客户提供的IID接口标识符,然后获得对应的接口的指针,返回对应的接口的指针;如果组件支持客户指定的接口,那么应返回S_OK以及相应的指针;若不支持,返回值应是E_NOINTERFACE,并将相应的指针返回值置成NULL。下面通过一个简单的例子来说明QueryInterface的简单实现:
比如有上述的一个结构;接口IX和IY都继承自IUnknown接口,组件CA实现了IX和IY接口,那么QueryInterface的实现应该像下面这样:
总结
QueryInterface理解起来比较简单,但是,它的理论知识还是必须要去掌握的,理论是一切的基础,没有理论作为支撑,任何实际的操作都不会那么可靠和可信,所以,这篇文章总结的偏于理论多一些。由于QueryInterface部分的内容比较多,使用一篇文章无法总结的齐全,所以,之后我还会继续总结关于QueryInterface的第二部分。