COM组件开发(一)—— 对象与接口 .

来源:互联网 发布:淘宝怎么改会员名字 编辑:程序博客网 时间:2024/05/16 12:04

一.前言

       在COM规范中,最基本的两个要素就是对象与接口,因为COM就是由这两者来共同实现的。COM对象在组件中是被封装起来的,客户代码只能通过接口来访问COM对象并享受其服务,由于客户与COM直接打交道的是COM接口,所以COM接口是COM最关键的要素。

二.COM对象

         COM对象其实就类似于C++中的对象,也就是说某个类的实例,包含了一组数据和操作。在COM模型中,COM对象的位置对于客户来说是透明的,即客户代码不需要直接初始化一个COM对象,而是COM库通过一个全局标识码GUID去对其进行初始化工作。GUID是一个128位的标识符,基本保证了COM对象的唯一性,另外COM接口也是用GUID来标识的。

封装特性

        COM对象的封装特性与C++的封装特性有所不同,COM对象的成员数据是以组件模块为边界,对于客户代码来说是看不见的,只能通过接口的函数去访问属性;而C++对象的封装特性则是语义上的封装,对于客户代码来说是可见的(一个C++类有什么样的成员变量是可见的,但是一般都是private或者pretected,无法直接访问)。

可重用性

          COM对象的可重用性在表现在聚合与包容,使得一个对象可以完全使用另一个对象的所有功能;而C++的重用性表现在继承上,则子类对象完全继承父类对象的属性与方法。聚合与包容可以使COM对象A能够完全重用COM对象B的功能,就像A实现了B的功能一样,并且在B的版本更新之后,A会动态地调用新版本的B而不需要重新编译、设置A,因此COM对象的重用是动态的。而C++对象则更多通过继承来实现源代码一级的重用,若更新了父类的定义,则子类必须重新编译,编译出来的可执行文件是在同一模块内的,重用性只体现在模块内部。而实际上在COM开发中同时使用了两者,即在COM内部使用了C++的代码级重用,在COM外部使用了组件重用。

多态性

          C++的多态性是其面向对象特性中最重要的一环,它是通过虚函数的机制来实现的。而COM对象也具有多态性,它是通过COM接口来实现的,即一个COM允许一个对象同时实现多个接口,因此,一个COM对象的多态性是由其接口实现的。


三.COM接口

          COM接口通常是一组以函数的逻辑集合,其命名一般以“I"为前缀,并且继承IUnKnown接口。COM对象可以提供多个COM接口,每个接口提供不同的服务,因此COM接口与COM对象一样,都是用GUID来标识的,客户通过GUID来获取接口指针,再通过接口指针获取对应的服务。

二进制特性

        接口规范并不建立在任何编程语言的基础上,而是在二进制一级的标准,任何语言只要有足够的表达能力对接口进行描述即可开发COM的应用(C++,C#,VB)。

接口不变性

       接口是客户与COM对象之间的桥梁,其重要性不言而喻,若接口总是变化,会使客户代码也跟着变化,这对于应用的开发是很不利的,所以接口一般是不变的。

继承特性

        COM接口的不变性,不代表接口不能拓展,可以通过接口继承的方式来进行拓展,与C++类的多继承相比,接口继承只允许单继承,并且继承的是接口函数的声明部分,并不包括接口的实现。

多态性

       多态是OOP的重要特点,对于COM来说也一样,而COM对象的多态性是通过COM接口的多态来体现的。

        IUnknown接口是COM的核心,因为所有其他的COM接口都必须从IUnknown继承。它包含三个接口函数:QueryInterface、AddRef和Release,其中QueryInterface用于接口查询,从COM对象的一个接口获得另一个接口,一个对象可能实现了多个接口,这样就可以通过QueryInterface在对象多个接口之间跳转从而获得多个接口提供的服务;AddRef与Release则用于管理COM对象的生命周期,当COM对象不再使用时需要释放,因此COM使用了引用计数的方法来对对象进行管理,当有一个用户获得接口指针后调用AddRef将引用计数加1,相反,当一个用户用完接口指针后就调用Release来使引用计数减1,这样当引用计数为0时,COM对象就可以从内存中释放。由于IUnknown提供了接口查询与生命周期控制两个功能,因此COM的每个接口都应该继承于它。

接口IUnknown的定义:

class IUnknown{public:     virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) = 0;     virtual ULONG __stdcall AddRef() = 0;     virtual ULONG __stdcall Release() = 0;};
可以看出IUnknown实质上就是一个含有纯虚函数的抽象类。
0 0
原创粉丝点击