COM原理及应用之自动化(Automation)对象
1、自动化技术
自动化技术既以前提到的OLE自动化。虽然自动化技术建立在COM基础上,但自动化要比COM应用广泛得多。一方面,自动化继承了COM的很多优点,比如语言无关、进程透明等特性;另一方面,自动化简化了COM的一些底层细节,比如属性和方法的处理、一组专用于自动化的数据类型等。自动化也是OLE的基础,所以可以把自动化看作COM和OLE中间的一项技术。自动化的核心是IDispatch接口,每一个自动化对象都必须实现IDispatch接口。自动化技术并不复杂,它实际上是COM的一个特例。
2、自动化产生与发展
COM的语言无关性在使用一些弱类型的高级语言时很受限制,而自动化为这些高级语言提供了另一条程序相互通信的直观且友好的途径。
自动化技术的发展与Visual Basic和VBA有直接的关系。首先,VBA(或VBScript)已经发展成为大多数Microsoft应用程序扩展的标准,其次,Microsoft Visual Basic开发工具的成功应用也推动了自动化对象的发展。自动化技术为Visual Basic与其他语言的协作开发提供了一条捷径。
通过自动化编程接口,不同应用程序之间的通信可以在VBA或者VBScript层次上进行,甚至根本不需要知道列集和RPC调用的概念。自动化是位于上层(应用层)的组件技术,它可以面对最终用户,比如宏语言编程。
自动化对象的IDispatch接口可以作为OLE的标准接口,由于OLE已经提供了标准的接口代理和存根组件,所以自动化对象即可以运行在DLL组件中,也可以运行在EXE组件中。如果在分布式环境下,那么自动化对象可以被远程客户创建或连接。
3、属性和方法
方法(method)和属性(property)是自动化对象的两个基本特性,方法是指自动化对象所提供的功能服务;而属性是指自动化对象的数据特征。
从本质上讲,属性是一个值,它既可以被设置,也可以被获取。
方法要比属性灵活得多,它们可以具有零个或多个参数,它们既可以设置也可以获取对象数据,最常见的是完成某些动作。
自动化对象的属性和方法都有符号化的名字,客户程序通过名字就可以访问到自动化对象的属性或者方法。
4、类型库和ODL
组件对象的类型信息是指它与外界进行交互的一些必要信息,包括组件的CLSID、它所支持接口的IID、接口的每个成员函数、成员函数的参数和返回值类型等等,类型信息中的数据类型也可以是自定义的数据类型,如C语言风格的结构、联合、枚举等。
Microsoft扩充了IDL形成ODL(object description language ,对象描述语言),可以描述组件对象的类型信息。一般来说,一个组件对象的类型信息包括每个接口的类型信息和对象的类型信息,接口类型信息的描述方法与 IDL完全兼容。接口类型信息使用interface 或dispinterface 关键字描述;对象类型信息使用coclass关键字进行描述。每个ODL文件可以描述多个组件对象,经过MIDL或者MkTypLib工具可编译得到类型库。通常把一个组件程序中的所有对象放在一个ODL文件中,并用library关键字描述库信息,包括类型库的ID(即LIBID)、类型库所使用的语言、版本等。在ODL文件中也可以使用importlib引入其他类型信息。
用MIDL实用工具编译ODL文件可以得到类型库文件,其后缀为TLB,也可以产生相应的.h头文件。
使用类型库的好处有两点。一是VB或者VBA可以使用类型库来浏览组件对象的方法和属性,它也可以利用类型库增强对属性和方法的访问;二是在实现自动化对象的IDispatch接口时,可以利用类型库向客户程序提供类型信息,这可使我们避免繁琐的类型处理。
5、IDispatch接口
成员函数Invoke是个关键函数,客户程序必须通过Invoke函数才能访问属性或方法,也可以说Invoke函数是自动化对象的命令翻译器。
6、自动化兼容的数据类型
自动化对象使用的基本数据类型为VCRIANT结构类型。整个VARIANT结构的大小为16字节,但它描述了所有自动化对象可以使用的数据类型。
7、IDispatchEx接口
IDispatch接口描述的类型信息是静态的,在运行过程中类型信息不会被改变,在编译时刻通过类型库就可以获得所有的类型信息。然而,在一些脚本语言中,我们需要在运行时刻动态提供类型信息,IDispatchEx接口这是适应这样的要求而建立起来的,它继承了IDispatch接口的成员函数。
8、自动化对象实现——类型库支持
9、自动化对象实现——Invoke函数实现
10、自动化对象实现——异常处理
11、自动化对象实现——多语种,本地化
12、自动化对象实现——用CreateStdDispatch函数实现自动化对象
13、自动化对象应用——双接口
自动化控制器通过IDispatch接口可以调用自动化对象的所有方法和属性,但由于这种调用是通过Invoke成员函数间接进行的,中间经过几重处理,调用的效率损失很大。当然这种方式为高级语言客户程序提供了极大的便利,不过有的客户程序不一定希望这种效率损失,它希望能够直接通过vtable调用到成员函数代码。为了同时满足这两种情形,自动化对象可以在实现IDispatch接口的基础上,把方法和属性函数也以接口成员函数的方法暴露出去,这样就形成了双接口(dual interface)的概念
14、自动化对象应用——迟绑定和早绑定
由于自动化对象使用类型库对参数类型进行检查,而类型库文件独立于自动化组件,因此,不仅自动化对象可以利用类型库实现它的IDispatch成员函数,自动化控制器也可以利用类型库对方法或属性的参数进行检查。
如果自动化控制器利用对象的类型库,在编译时刻对参数类型和返回值类型进行检查,并直接用分发ID调用Invoke函数,我们把这种调用方法称为早绑定(early binding)技术。
相对应地,控制器也可以在运行时刻通过IDispatch接口的成员函数获得类型信息,当它访问一个属性或方法时,它要调用IDispatch::GetIDsOfNames,以便根据符号化名字找到分发ID,我们把这种调用称为迟绑定(late binding)技术。
选择使用早绑定或者迟绑定取决于控制器的运行环境,而调用效率并不成为判断的依据。
15、自动化对象应用——自动化集合对象
集合对象也是一个自动化对象,但它有一些特殊的要求。首先,作为一组同类对象(或数值)的容器对象,它必须提供枚举这些成员的方法;其次,它必须支持Add、Remove和Item方法以及Count属性。
16、自动化对象应用——一IDispatch作为出接口
17、自动化对象应用——自动化控制器
18、自动化对象编程——MFC对自动化对象的支持
19、自动化对象编程——COleDispatchDriver类
20、自动化对象编程——在Visual Basic中使用自动化对象
文章出处:http://www.diybl.com/course/3_program/c++/cppxl/20081118/151928.html