COM原理及组件开发(课堂PPT)_第1页
COM原理及组件开发(课堂PPT)_第2页
COM原理及组件开发(课堂PPT)_第3页
COM原理及组件开发(课堂PPT)_第4页
COM原理及组件开发(课堂PPT)_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1哈尔滨工业大学计算机学院唐好选Email:2主要内容主要内容uCOMCOM的基本原理的基本原理u构件对象模型构件对象模型COM/DCOMCOM/DCOMu基于基于COMCOM构件的开发构件的开发3u COM是微软提出的第一个构件模型,源于是微软提出的第一个构件模型,源于OLE: Object Link and Embedding(动态链接和嵌入动态链接和嵌入)OLE1 采用采用DDE(Dynamic Data Exchange:动态数据交换动态数据交换) 在不同的程序之间进行通信在不同的程序之间进行通信DDE缺点缺点: 建立在建立在Windows消息机制基础上,效率低、稳消息机制基础上,效率

2、低、稳定性不好、使用不方便定性不好、使用不方便 u COM是为克服上述不足而出现的是为克服上述不足而出现的 COM 技术的发展技术的发展4u COM定义了客户与构件之间互操作的标准,包括规约与实定义了客户与构件之间互操作的标准,包括规约与实现两个部分现两个部分u 规约部分定义了构件之间的通信机制,这些规约不依规约部分定义了构件之间的通信机制,这些规约不依赖于任何特定的语言和操作系统赖于任何特定的语言和操作系统u 实现部分就是实现部分就是COM库,为库,为COM规约的具体实现提供了规约的具体实现提供了一些核心服务一些核心服务u COM仅支持同一台计算机上(当然是仅支持同一台计算机上(当然是Win

3、dows操作系统)操作系统)的互操作,不支持分布式计算环境的互操作,不支持分布式计算环境COM 技术的发展技术的发展5u 将将COM技术延伸到分布计算环境,产生了所谓的技术延伸到分布计算环境,产生了所谓的DCOM (Distributed COM,分布构件对象模型分布构件对象模型) 用网络协议代替用网络协议代替 本地进程之间的通信本地进程之间的通信 针对分布环境提供了新特性:针对分布环境提供了新特性: 位置透明位置透明 网络安全性网络安全性 跨平台调用跨平台调用 等等u 为了满足企业级应用的需求,推出了微软事务服务器为了满足企业级应用的需求,推出了微软事务服务器 (MTS: Microsoft

4、 Transaction Server),把应用系统的客户程把应用系统的客户程序、应用构件和各种资源有机结合起来,为分布式企业应序、应用构件和各种资源有机结合起来,为分布式企业应用提供了一种服务器端的构件运行和部署环境用提供了一种服务器端的构件运行和部署环境COM 技术的发展技术的发展6u 为了使为了使Windows真正成为企业应用平台,微软推出了分布真正成为企业应用平台,微软推出了分布式网络应用体系结构(式网络应用体系结构(Windows DNA: Distributed interNet Application Architecture),),DNA是一个完整的、多层的企是一个完整的、多层

5、的企业应用体系结构:包含工具、数据库、操作系统、编程模业应用体系结构:包含工具、数据库、操作系统、编程模型和应用服务等型和应用服务等u 随着随着Windows 2000的发布,微软进一步把的发布,微软进一步把COM、DCOM、MTS统一起来,形成了真正适合于企业级应用的构件技术:统一起来,形成了真正适合于企业级应用的构件技术:COM+u 可以认为:可以认为:COM/DCOM + MTS = COM+u COM+是一种中间件技术规约,提供操作系统级的分布是一种中间件技术规约,提供操作系统级的分布式式“服务服务”COM 技术的发展技术的发展7Window DNA8u 是一个服务器端的开发平台,包括

6、是一个服务器端的开发平台,包括u Windows NT/2000/2003 提供运行环境和支持提供运行环境和支持u COM/DCOM u MSMQ 消息队列产品,支持构件间异步通信消息队列产品,支持构件间异步通信u MTS 管理构件的应用服务管理构件的应用服务u Microsoft Wolfpack 支持集群服务器的软件支持集群服务器的软件u Microsoft SQL Server u Microsoft IIS Web服务器服务器u Microsoft Management Console 部署和管理工具部署和管理工具Window DNA9COM+基本结构基本结构COM+目录负载平衡驻留内

7、存数据库对象池新的事件模型构件管理和部署JIT激活COM+ MTS事务支持资源分发管理安全模型易于管理远程支持 DCOM分布式构件服务 COM基于接口的编程模型基本的构件服务10uCOM(Component Object Model),组件对象模型,是一),组件对象模型,是一种以组件为发布单元的对象模型,这种模型使得各个软件组件种以组件为发布单元的对象模型,这种模型使得各个软件组件可以用一种统一的方式进行交互可以用一种统一的方式进行交互uCOM是一种协议,它建立了一个软件模块同另一个软件模块是一种协议,它建立了一个软件模块同另一个软件模块之间的连接,提供了组件之间进行交互的规范,也提供了实现之

8、间的连接,提供了组件之间进行交互的规范,也提供了实现交互的环境交互的环境u当这种连接建立起来后,两个模块之间就可以通过当这种连接建立起来后,两个模块之间就可以通过“接口接口”的机制来进行通讯,这些接口既不需要静态的或动态的连接入的机制来进行通讯,这些接口既不需要静态的或动态的连接入口点,也不需要编码很复杂的地址口点,也不需要编码很复杂的地址什么是什么是COM?11u全局唯一标识符(全局唯一标识符(Global Unique IDentifier)来源于)来源于OSF的通的通用统一标识符用统一标识符UUID(Universal Unique IDentifier),是一个),是一个128位整数位

9、整数u用于标识用于标识COM对象对象(CLSID)和接口和接口(IID)u由于空间足够大由于空间足够大, 冲突较小冲突较小.可以用编程的方法生成具有唯一性可以用编程的方法生成具有唯一性的的GUID uVC: UUIDGEN.EXE, GUIDGEN.EXEu对对GUID值的传递通常通过引用进行值的传递通常通过引用进行COM基本概念:基本概念:GUID12基本概念:基本概念:COM对象对象/COM构件构件/COM接口接口COM构件对象1对象2接口1接口2 接口3接口413基本概念:基本概念:COM对象和对象和COM构件构件u在在COM规约中,规约中,“构件构件”和和“对象对象”经常混淆,所谓经常

10、混淆,所谓COM对对象是指符合象是指符合COM规则的规则的CoClass(构件类)的实例,每一个(构件类)的实例,每一个COM对象都有一个对象都有一个GUID,称为,称为CLSID(CoClassID)uCOM构件是指以编译后的形式提供一组功能的构件是指以编译后的形式提供一组功能的COM对象对象u独立于具体编程语言独立于具体编程语言u一个构件可以由多个类实现一个构件可以由多个类实现u以二进制形式(以二进制形式(DLL或或EXE)发布)发布u可以在不妨碍客户的形式下被升级可以在不妨碍客户的形式下被升级u可以透明地在网络上被重新分配可以透明地在网络上被重新分配14uCOM接口是接口是COM规范的核

11、心内容,是规范的核心内容,是COM对象显示出来的对象显示出来的所有信息,是一组逻辑上相关的函数集合所有信息,是一组逻辑上相关的函数集合u每一个接口都有一个每一个接口都有一个GUID,称为接口标识符(简称,称为接口标识符(简称IID:Interface IDentifier)uCOM接口具有不变性,只允许单继承接口具有不变性,只允许单继承u一个一个COM对象可以实现多个接口,这体现了对象可以实现多个接口,这体现了COM对象的多对象的多态性,这些接口由态性,这些接口由IUnknown接口来管理接口来管理u在在C+中中,可以用抽象基类来定义可以用抽象基类来定义COM接口接口基本概念:基本概念:COM

12、接口接口15 新版本构件的处理新版本构件的处理uCOM接口永远不会变化接口永远不会变化 :一个一个IID就是一个接口,当对组件就是一个接口,当对组件进行升级时,一般不会修改已有的接口,而是加入一些新接口进行升级时,一般不会修改已有的接口,而是加入一些新接口u当下列条件中的任何一个变化时,应给新接口指定新当下列条件中的任何一个变化时,应给新接口指定新IIDu接口中函数数目接口中函数数目u接口中函数顺序接口中函数顺序u某个函数的参数某个函数的参数u某个函数参数的顺序某个函数参数的顺序u某个函数参数的类型某个函数参数的类型u函数可能的返回值函数可能的返回值u函数返回值的类型等函数返回值的类型等u不同

13、版本接口的命名不同版本接口的命名:在老名称后加一个数字在老名称后加一个数字16u是所有是所有COM对象都必须实现的接口,其它接口都直接或间接对象都必须实现的接口,其它接口都直接或间接继承继承IUnknown(IID为为00000000-0000-0000-C000-000000000046 )接)接口,包含三个基本操作口,包含三个基本操作uAddRef:提供生存周期管理功能,增加对象引用计数:提供生存周期管理功能,增加对象引用计数uRelease:提供生存周期管理功能,用于释放对象:提供生存周期管理功能,用于释放对象uQueryInterface:负责向客户提供接口查询功能:负责向客户提供接口

14、查询功能基本概念:基本概念:IUnknown接口接口IUknown接口的定义,定义在接口的定义,定义在win32 SDK中的中的UNKNWN.h头文件中:头文件中:interface IUnkown virtual HRESULT _stdcall QueryInterface( const IID&, void *ppv) = 0; virtual ULONG_stdcall AddRef() = 0; virtual ULONG_stdcall Release() = 0; 17u微软接口定义语言微软接口定义语言MIDL(Microsoft Interface Definition

15、 Language)是定义)是定义COM接口的申述式语言接口的申述式语言u通过独立于具体编程语言的方式来定义接口通过独立于具体编程语言的方式来定义接口u该语言基于该语言基于OSF分布式计算环境(分布式计算环境(DCE)远程过程调用)远程过程调用(RPC)的接口描述语言)的接口描述语言IDLuCOM规范使用的规范使用的IDL接口描述语言不仅可用于接口描述语言不仅可用于COM接口,接口,同时还定义了一些常用的数据类型,也可描述自定义的数据结同时还定义了一些常用的数据类型,也可描述自定义的数据结构,对于接口的成员函数,可以指定每个参数的类型、输入输构,对于接口的成员函数,可以指定每个参数的类型、输入

16、输出特性,甚至可支持变长度的数组的描述出特性,甚至可支持变长度的数组的描述uMIDL支持指针类型,与支持指针类型,与C/C+类似类似基本概念:接口定义语言基本概念:接口定义语言18u接口定义例:接口定义例:interface IDictionary HRESULT Initialize(); HRESULT LoadLibrary(in string); HRESULT InsertWord(in string, in string); HRESULT DeleteWord(in string); HRESULT LookWorld(in string,out string*); HRESUL

17、T RestoreLibrary(in string); HRESULT FreeLibrary();基本概念:接口定义语言基本概念:接口定义语言19uCOM接口是一个二进制标准,客户同接口的连接并不是通过接口是一个二进制标准,客户同接口的连接并不是通过其名称或其成员函数的名称来实现的,而是通过其在内存块中其名称或其成员函数的名称来实现的,而是通过其在内存块中的位置完成的的位置完成的uCOM接口是一个包含一个函数指针数组的内存结构,每一个接口是一个包含一个函数指针数组的内存结构,每一个数组元素包含的是一个由组件所实现的函数的地址数组元素包含的是一个由组件所实现的函数的地址uC+通过纯抽象基类实

18、现通过纯抽象基类实现COM接口,实际上是定义了一个内接口,实际上是定义了一个内存块的结构,但此内存只是在派生类中实现此抽象基类时才会存块的结构,但此内存只是在派生类中实现此抽象基类时才会被分配,派生类继承此抽象基类时将继承此内存结构被分配,派生类继承此抽象基类时将继承此内存结构COM接口接口20Vtbl指针指针虚拟函数表虚拟函数表pIXIX&Fx1&Fx2&Fx3&Fx4虚拟函数表虚拟函数表uCOM接口的内存结构同接口的内存结构同C+编译器为抽象基类所生成的内存编译器为抽象基类所生成的内存结构是相同的,对于如下利用纯抽象基类方式定义的接口结构是相同的,对于如下利

19、用纯抽象基类方式定义的接口interface IX virtual void _stdcall Fx1()=0; virtual void _stdcall Fx2()=0; virtual void _stdcall Fx3()=0; virtual void _stdcall Fx4()=0; 21u提高接口实现的灵活性,实现抽象基类的类可能会将特定于提高接口实现的灵活性,实现抽象基类的类可能会将特定于实例的信息同实例的信息同vtbl一块保存一块保存例子例子:一个一个实现实现接口接口IX的类的类CA,CA包含包含2个数据个数据:class CA : public IX public: vi

20、rtual void_stdcall Fx1() virtual void_stdcall Fx2() virtual void_stdcall Fx3() virtual void_stdcall Fx4() double Data1; double Data2;Vtbl的作用的作用22Vtbl指针指针虚拟函数表虚拟函数表IX&Fx1&Fx2&Fx3&Fx4Data1Data2pAFx1Fx2Fx3Fx4CA实例数据和实例数据和vtbl一起保存一起保存u注意:注意:COM组件决不会访问任何实例数据,在组件决不会访问任何实例数据,在COM中,对中,对一个组件的访

21、问只能通过函数完成,绝不能直接通过变量一个组件的访问只能通过函数完成,绝不能直接通过变量u纯抽象基类只有虚拟函数,没有实例数据纯抽象基类只有虚拟函数,没有实例数据23两个实例两个实例 共享同一共享同一VtblVtbl指针指针虚拟函数表虚拟函数表&Fx1&Fx2&Fx3&Fx4Data1Data2pA1pA2Fx1Fx2Fx3Fx4CAVtbl指针指针Data1Data2共享同一共享同一Vtbl24Vtbl指针指针虚拟函数表虚拟函数表IXQueryInterfaceAddRefRelease&FxpAQueryInterfaceAddRefReleaseF

22、xCA所有COM接口都必须继承IUnknown接口,支持其定义的三个函数,而且必须是接口vtbl的前三个函数25uIUnknown * CreateInstance();创建构件时,客户可以使用创建构件时,客户可以使用CreateInstance,而不是而不是newuCreateInstance的定义:的定义: IUnknown * CreateInstance() IUnknown * pI = static_cast (new foo); pI - AddRef(); return pI; IUnknown指针的获取指针的获取26u一个一个COM对象(构件)可以实现多个接口对象(构件)可以

23、实现多个接口.u使用使用QueryInterface查询某个构件是否支持某个特定的接口查询某个构件是否支持某个特定的接口 void foo(Iunknown * pI)IX * pIX = NULL;HRESULT hr = pI-QueryInterface(IID_IX, (void *)&pIX);If (SUCCEEDED(hr) pIX-Fx(); 接口查询接口查询27u假定存在类假定存在类 CA,继承接口继承接口 IX 与与 IY HRESULT _stdcall CA: QueryInterface(const IID& iid, void * ppv) if (

24、iid = IID_IUnknown) *ppv = static_cast(this); else if (iid = IID_IX) *ppv = static_cast(this); else if (iid = IID_IY) *ppv = static_cast(this); else *ppv = NULL; return E_NOINTERFACE; static_cast(*ppv)-AddRef();return S_OK;QueryInterface的实现的实现28uQueryInterface返回的总是同一个返回的总是同一个IUnknown指针指针u若客户曾经获取过某个接

25、口若客户曾经获取过某个接口,那么它将总能获取此接口那么它将总能获取此接口u客户可以再次获取已经拥有的接口客户可以再次获取已经拥有的接口u客户可以返回到起始接口客户可以返回到起始接口u若能够从某个接口获取某特定接口若能够从某个接口获取某特定接口,则可以从则可以从(该构件的该构件的)任任意接口获取此接口意接口获取此接口QueryInterface的实现规则的实现规则29u 通过函数通过函数AddRefAddRef与与ReleaseRelease实现实现u 控制构件的生命期控制构件的生命期u 解决内存管理问题解决内存管理问题u 使构件能够自己将自己删除使构件能够自己将自己删除u 使用规则使用规则u

26、返回接口指针之前调用返回接口指针之前调用AddRef;AddRef;u 使用完接口之后调用使用完接口之后调用Release;Release;u 赋值之后调用赋值之后调用AddRef;AddRef;引用计数引用计数30在什么层次上进行计数:构件在什么层次上进行计数:构件?对象对象?接口接口?构件构件构件引用记数构件引用记数对象引用记数对象引用记数对象引用记数对象引用记数对象对象1对象对象2接口接口接口接口接口接口接口接口接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数接口引用记数引用计数的实现方式引用计数的实现方式31u 函数的参数中使用接口指针变量函数的参数

27、中使用接口指针变量u 对于输入参数,被调函数不必改变计数对于输入参数,被调函数不必改变计数u 对于输出参数,相当于生成了一个新的接口指针变量,对于输出参数,相当于生成了一个新的接口指针变量,因此在返回之前,需要使计数增因此在返回之前,需要使计数增1 1u 对于输入输出参数,参数修改之前计数减对于输入输出参数,参数修改之前计数减1 1,修改之后,修改之后计数加计数加1 1,若参数未被修改,计数不变,若参数未被修改,计数不变u 对于局部接口指针变量,不改变计数对于局部接口指针变量,不改变计数u 对于全局接口指针变量,作为参数传给某函数之前,计数对于全局接口指针变量,作为参数传给某函数之前,计数增增

28、1 1,返回之后计数减,返回之后计数减1 1,C+C+类成员变量为接口指针变量类成员变量为接口指针变量时也采用此规则时也采用此规则引用计数的更详细的规则引用计数的更详细的规则32uCOM构件可以和客户机程序在同一个进程中,也可构件可以和客户机程序在同一个进程中,也可以在不同的进程中以在不同的进程中u前者称为进程内构件前者称为进程内构件(INPROC_SERVER)u后者称为进程外构件后者称为进程外构件(LOCAL_SERVER )u如果是如果是DCOM,进程外构件还包括,进程外构件还包括uCLSCTX_REMOTE_SERVER COM构件与客户机之间的通信机制构件与客户机之间的通信机制33u

29、在在Windows平台上,进程内构件以动态链接库平台上,进程内构件以动态链接库(DLL)形式实现形式实现u由于由于DLL包含一个导出函数表,客户机程序和包含一个导出函数表,客户机程序和DLL动态连接时动态连接时会建立一张表,把客户机调用和会建立一张表,把客户机调用和DLL中函数的地址连接起来中函数的地址连接起来 因此客户机程序和进程内构件可通过直接函数调用进行交互因此客户机程序和进程内构件可通过直接函数调用进行交互u进程内构件程序也可称作进程内服务程序进程内构件程序也可称作进程内服务程序COM构件与客户机之间的通信机制构件与客户机之间的通信机制34u对于进程外构件,由于进程之间相互屏蔽,客户机

30、进程不能直对于进程外构件,由于进程之间相互屏蔽,客户机进程不能直接调用构件进程,需要遵循操作系统对进程间通信所做的规定,接调用构件进程,需要遵循操作系统对进程间通信所做的规定,在在Windows平台上,进程外构件以平台上,进程外构件以EXE实现,实现,COM采用本地过采用本地过程调用(程调用(LPC)作为进程间通信机制)作为进程间通信机制COM构件与客户机之间的通信机制构件与客户机之间的通信机制客户机进程客户机应用进程内构件进程内对象COM本地对象代理服务器进程COM本地对象代理COM桩LPC35u当调用组件的时候,其实是依靠代理(运行在本地)和存根当调用组件的时候,其实是依靠代理(运行在本地

31、)和存根(运行在远端)之间的通讯完成的(运行在远端)之间的通讯完成的组件调用机制组件调用机制36uCOM不仅定义了客户与构件之间交互的规约,而且提供了全不仅定义了客户与构件之间交互的规约,而且提供了全面的实现细节,面的实现细节,COM的实现与操作系统密切相关,包括的实现与操作系统密切相关,包括:uCOM库(库(COM Library)u系统注册表(系统注册表(windows registry)u类工厂类工厂uCOM服务器服务器COM的实现的实现37u 是是COM标准的系统级实现,为标准的系统级实现,为COM对象的标识和创建、内对象的标识和创建、内存管理、构件程序的卸载等提供了一组标准接口和辅助

32、函数存管理、构件程序的卸载等提供了一组标准接口和辅助函数u 在在Windows系统中,系统中,COM库主要包含在库主要包含在OLE32.dll、OLE32.lib和和RPCSS.dll文件中文件中u COM库很多地方直接用到了库很多地方直接用到了Windows系统的一些特性,例系统的一些特性,例如系统注册表和动态链接库,如系统注册表和动态链接库,COM通过注册表查找本地服通过注册表查找本地服务器务器(即即EXE程序程序) 以及程序名与以及程序名与CLSID的转换的转换 COM库库38COM库库uCOM库中常用的函数库中常用的函数u 初始化函数初始化函数u 与与GUID相关的函数相关的函数u 对

33、象创建函数对象创建函数u 内存管理函数内存管理函数39u在使用在使用COM库中的其他函数之前,进程必须先调用库中的其他函数之前,进程必须先调用 HRESULT CoInitialize(void * reserved) /参数必须为NULL 注意:对每一个进程,COM库函数只需要初始化一次,由于COM主要用于创建组件,进程内组件无需初始化COM库u在退出之前调用在退出之前调用 void CoUninitialize(void * reserved) 注意:和初始化函数配合使用u由于OLE建立在COM基础上,初始化需要调用OleInitialize() 函数和OleUnInitialize()

34、函数uDCOM使用CoInitializeEx函数进行初始化初始化函数初始化函数40关于关于HRESULTu组件组件API及接口指针中,除了及接口指针中,除了IUnknown:AddRef()IUnknown:Release()两个函数外,其它所有的函数,都以两个函数外,其它所有的函数,都以 HRESULT 作为返回值作为返回值 uHRESULT 是一个双字节的值是一个双字节的值u最高位最高位0表示成功表示成功u最高位最高位1表示错误表示错误41uHRESULTuS_OK 0 x00000000 成功uS_FALSE 0 x00000001 函数成功执行完成,但返回时出错uE_INVALIDA

35、RG 0 x80070057 参数有错误uE_OUTOFMEMORY 0 x8007000E 内存申请错误uE_UNEXPECTED 0 x8000FFFF 未知的异常uE_NOTIMPL 0 x80004001 未实现功能uE_FAIL 0 x80004005 没有详细说明的错误uE_POINTER 0 x80004003 无效的指针uE_HANDLE 0 x80070006 无效的句柄uE_ABORT 0 x80004004 终止操作uE_ACCESSDENIED 0 x80070005 访问被拒绝uE_NOINTERFACE 0 x80004002 不支持接口关于关于HRESULT42u

36、由于注册表中包含的是由于注册表中包含的是CLSID的字符串表示,因此需要一些的字符串表示,因此需要一些函数完成函数完成CLSID与表示与表示CLSID的字符串之间的转换的字符串之间的转换 StringFromGUID2 :将将GUID转换为字符串类型转换为字符串类型其它:其它:StringFromCLSID :将:将CLSID转化为文本串转化为文本串StringFromIID :将:将IID转化为文本串转化为文本串CLSIDFromString :将一个文本串转化为:将一个文本串转化为CLSIDIIDFromString :将一个文本串转化为:将一个文本串转化为IIDIsEqualGUID/I

37、sEqualIID/IsEqualCLSIDCLSIDFromProgID与与GUID(CLSID)相关的函数相关的函数43对象创建函数:对象创建函数:CoGetClassObjectCoCreateInstanceCoCreateInstanceExCoRegisterClassObjectCoRevokeClassObjectCoDisconnectObject内存管理函数:内存管理函数:CoTaskMemAllocCoTaskMemReallocCoTaskMemFreeCoGetMalloc44一个例子:一个例子:IX * pIX = NULL;HRESULT hr = :CoCrea

38、teInstance( CLSID_Component1,NULL,CLSCTX_INPROC_SERVER,IID_IDX,(void *) &pIX);if (SUCCEEDED(hr) pIX - FX();pIX - Release();45Windows 注册表注册表u系统注册表是一个全操作系统范围公用的信息仓库,可用作客系统注册表是一个全操作系统范围公用的信息仓库,可用作客户程序、构件程序和户程序、构件程序和COM库三者交换有关库三者交换有关COM对象信息和接口对象信息和接口信息的场所信息的场所uWindows操作系统的系统注册表中包括硬件、软件、配置及用操作系统的系统注册

39、表中包括硬件、软件、配置及用户等各种信息户等各种信息u由由REGEDIT.EXE启动启动u由由REGSVR32.EXE来注册某个构件来注册某个构件u系统注册表是一个由许多元素构成的层次结构,每个元素均被系统注册表是一个由许多元素构成的层次结构,每个元素均被称作一个关键字,每个关键字可以包含一系列子关键字称作一个关键字,每个关键字可以包含一系列子关键字u例如:例如: HKEY_CLASSES_ROOTCLSIDProgID 等等464748通过通过Windows 注册表注册组件注册表注册组件u 注册文件注册文件 REGEDIT4 HKEY_CLASSES_ROOTTEST =“TESTCOM H

40、KEY_CLASSES_ROOTTESTCLSID =b91c46bc-5841-4f41-95f3-daade42b343649组件注册其它方法组件注册其它方法u情况情况1:当使用当使用 ATL(Active Template Library) 编写组件编写组件程序,编译成功后,程序,编译成功后,IDE 自动完成注册自动完成注册;u情况情况2:当使用当使用 MFC 编写组件程序,由于编译器不知道编写编写组件程序,由于编译器不知道编写的是否是的是否是 COM 组件,所以无法自动注册。组件,所以无法自动注册。可执行菜单可执行菜单“ToolsRegister Control”来注册来注册u情况情况

41、3:当写了一个具有当写了一个具有 COM 功能的功能的 EXE 程序时,程序时,运行一运行一次该程序即可完成组件注册次该程序即可完成组件注册u情况情况4:当需要使用第三方提供的组件程序时,可通过命令当需要使用第三方提供的组件程序时,可通过命令行运行行运行“regsvr32.exe 文件名文件名”来注册来注册,反注册的方法是反注册的方法是“regsvr32.exe /u 文件名文件名”; 50关于注册组件关于注册组件u情况情况5:当需要在程序中(如安装程序)执行注册,那么:当需要在程序中(如安装程序)执行注册,那么: typedef HRESULT (WINAPI * FREG)(); TCHA

42、R szWorkPath MAX_PATH ; :GetCurrentDirectory( sizeof(szWorkPath), szWorkPath ); :SetCurrentDirectory( 组件目录 ); HMODULE hDLL = :LoadLibrary( 组件文件名 ); if(hDLL) FREG lpfunc = (FREG):GetProcAddress( hDLL, _T(DllRegisterServer) ); if ( lpfunc ) lpfunc(); :FreeLibrary(hDLL); :SetCurrentDirectory(szWorkPath

43、);51u 类工厂是能够创建其它类工厂是能够创建其它COM对象的特殊对象的特殊COM对象,类工对象,类工厂支持一个特殊的接口厂支持一个特殊的接口IClassFactory,为例化,为例化CoClass构件构件类提供了一种标准机制类提供了一种标准机制u 每一个每一个COM对象类应该有一个相应的类工厂对象对象类应该有一个相应的类工厂对象u IClassFactory接口中定义了两个重要的操作接口中定义了两个重要的操作u CreateInstance:生成生成COM对象并返回所请求接口的指针对象并返回所请求接口的指针u LockServer:负责在内存中保持:负责在内存中保持COM构件构件类工厂类工

44、厂52u 具有四个输入参数和一个输出参数:第一个参数表示待创具有四个输入参数和一个输出参数:第一个参数表示待创建组件的建组件的CLSID,第三个参数表示组件,第三个参数表示组件执行上下文执行上下文,第四,第四个参数表示待使用接口的个参数表示待使用接口的IID,输出代表接口指针,输出代表接口指针u 执行上下文可通过如下值组合执行上下文可通过如下值组合 CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVERu 无法为组件的创建加上限制条件;用该函数建立组件后,无法为组件的创建加上限

45、制条件;用该函数建立组件后,无法控制组件的装载位置或无法检查客户是否有权限创建无法控制组件的装载位置或无法检查客户是否有权限创建该组件,该组件,CoCreateInstances函数的灵活性不足函数的灵活性不足u 有必要使用一个专门用于创建所需组件的组件:类厂有必要使用一个专门用于创建所需组件的组件:类厂关于关于CoCreateInstanceCoCreateInstance的分析的分析53类厂类厂(Class Factory)(Class Factory)u如果使用类厂,如果使用类厂,CoCreateInstance实际上未直接创建实际上未直接创建COM构件构件,而是创建了一个被称为类厂的构

46、件,类厂构件的唯一功能是创建而是创建了一个被称为类厂的构件,类厂构件的唯一功能是创建其他构件其他构件u客户可以通过类厂所支持的接口来对类厂创建构件的过程加以客户可以通过类厂所支持的接口来对类厂创建构件的过程加以控制控制uCoCreateInstance首先调用首先调用CoGetClassObjec获取类厂中的获取类厂中的IClassFactory接口的指针接口的指针u然后使用返回的指针调用然后使用返回的指针调用IClassFactory:CreateInstance完完成新组件的创建成新组件的创建54IClassFactory:用于创建构件的标准接口用于创建构件的标准接口Interface I

47、ClassFactory: IUnknownHRESULT _stdcallCreateInstance( IUnknown * pUnknownOuter,const IID & iid,void * ppv );HRESULT _stdcall LockServer(BOOL block);u另一个创建接口:另一个创建接口:IClassFactory2增加了许可和权限功能,增加了许可和权限功能,通过使用该接口,类厂可以保证客户只能获得他能合法访问通过使用该接口,类厂可以保证客户只能获得他能合法访问的组件,并具有此组件的访问授权的组件,并具有此组件的访问授权55CoCreateIns

48、tance 通过通过 CoGetClassObject实现实现HRESULT CoCreateInstance (const CLSID& clsid,IUnknown * pUnknownOuter,DWOED dwClsContext,const IID& iid,void * ppv) *ppv = NULL; IClassFactory * pIFactory = NULL; HRESULT hr = CoGetClassObject(clsid, dwClsContext, NULL, IID_IClassFactory, (void)* &pIFactory

49、); if (SUCCEEDED(hr)hr=pIFactory-CreateInstance(pUnknownOuter, iid, ppv);pIFactory - Release(); return hr;56组件创建过程组件创建过程客户COM库DLL类厂组件CoCreateInstanceCoGetClassObjectDllGetClassObjectNew CFactoryIClassFactory:CreateInstance(IID_IX)New CAIClassFactory:ReleasepIX-Fx()57u 是指包含一个或多个是指包含一个或多个COM对象类和相应的类工厂

50、,能向客对象类和相应的类工厂,能向客户提供服务的一个程序(户提供服务的一个程序(EXE)或库()或库(DLL)COM服务器服务器客户机 构件 类对象对象COM库系统注册表CLSID SERVER.DLL1.客户调用CoGetClassObject2.COM定位所请求的类对象3.构件被启动4.类对象创建成功后将IClassFactory接口指针经COM库返回给客户机5.客户调用IClassFactory创建实例7.接口将指针返回给客户机6.对象被创建58COM的复用方式的复用方式uCOM不允许直接继承,但可通过包含和聚合来代替继承不允许直接继承,但可通过包含和聚合来代替继承u如果一个构件如果一个

51、构件B使用另外一个构件使用另外一个构件A,我们称使用者,我们称使用者B为外部为外部构件,被使用者构件,被使用者A为内部构件为内部构件, 则称:外部构件则称:外部构件B包含(聚合)了内部构件包含(聚合)了内部构件Au包含与聚合是包含与聚合是COM的两种复用方式(模型),为系统升级和的两种复用方式(模型),为系统升级和扩展提供支持扩展提供支持59包含(包含(Containment)对象对象A对象对象BIYIXIXIUnknown60客户程序对象B对象A调用调用ISomeInterfaceISomeInterface包含(包含(Containment)61u对象对象B的成员函数在调用对象的成员函数在

52、调用对象A的接口之前或之后可以进行的接口之前或之后可以进行其他任何操作其他任何操作uIX 提供的功能可以超过提供的功能可以超过IXu对象对象B是对象是对象A的客户,而对象的客户,而对象B的客户看到的只是对象的客户看到的只是对象B显露出的接口(显露出的接口(IY和和IX)u对象对象A的创建与释放完全在对象的创建与释放完全在对象B内部进行,对象内部进行,对象A的生命的生命期包含在对象期包含在对象B的生命期内的生命期内包含(包含(Containment)62聚合聚合 (Aggregation)对象对象A对象对象BIYIXIUnknownIUnknown63聚合聚合 (Aggregation)客户程序

53、对象B对象A调用传递ISomeInterfaceIOtherInterface64u聚合可看作是包含的一个特例,聚合更好地体现了复用聚合可看作是包含的一个特例,聚合更好地体现了复用u虽然对象虽然对象A A直接向对象直接向对象B B的客户提供服务,但对象的客户提供服务,但对象B B的客户感觉的客户感觉不到对象不到对象A A的存在,对象的存在,对象A A的生存期受到对象的生存期受到对象B B的控制的控制u实现聚合的关键在于实现聚合的关键在于QueryInterfaceQueryInterfaceu当客户向对象当客户向对象B B请求请求IXIX时时, ,对象对象B B的的QueryInterface

54、QueryInterface返回对返回对象象A A的的IXIX指针指针u存在问题:存在问题:u(1 1)从)从IXIX如何得到如何得到IYIY?u(2 2)从)从IXIX得到的得到的IunknownIunknown如何与从如何与从IYIY得到的得到的IUnknown IUnknown 相同?相同?聚合聚合 (Aggregation)(Aggregation)65u包含的复用性建立在客户包含的复用性建立在客户/ /服务器模式上,而服务器模式上,而聚合的复用性需要内部构件提供支持聚合的复用性需要内部构件提供支持u复用方式的选择:复用方式的选择:u当内部构件提供的接口完全满足要求时,当内部构件提供的

55、接口完全满足要求时,使用聚合合适使用聚合合适u当内部构件提供的接口与需求类似时,使当内部构件提供的接口与需求类似时,使用包含合适用包含合适u在一个对象中可以同时使用两种复用方式在一个对象中可以同时使用两种复用方式包含与聚合的使用包含与聚合的使用66u 自动化是允许高级语言使用构件的自动化是允许高级语言使用构件的COM应用技术,自动化应用技术,自动化的核心是的核心是IDispatch接口,自动化对象就是实现了接口,自动化对象就是实现了IDispatch接接口的口的COM对象对象u IDispatch接口是自动化对象必须实现的接口接口是自动化对象必须实现的接口, IDispatch在在IUnkow

56、n接口的基础上增加了如下操作接口的基础上增加了如下操作u GetIDsOfNames 操作负责返回操作或属性及其参数名字的操作负责返回操作或属性及其参数名字的分发标识符(分发分发标识符(分发ID,即,即DISPID:用于管理属性和操作):用于管理属性和操作)u GetTypeInfo 处理对象类型信息处理对象类型信息u GetTypeInfoCount 处理对象类型信息处理对象类型信息u Invoke 是是IDispatch的核心操作,根据分发的核心操作,根据分发ID执行相应函数执行相应函数COM的动态激活机制的动态激活机制-自动化自动化67COM的动态激活机制的动态激活机制-自动化自动化构件

57、构件客户机客户机IDispatch指针对象对象Vtable指针IDispatch VtableInvokeInvoke(DISP d,) Switch(d)Case 1: Method1();Case 2: Method2()Method2() Method1() 68u Invoke操作和分发操作和分发ID机制使得运行时动态绑定属性和方法成机制使得运行时动态绑定属性和方法成为可能,但灵活性的代价是效率的降低。如果将为可能,但灵活性的代价是效率的降低。如果将DISP硬编码硬编码在应用中而不是频繁调用在应用中而不是频繁调用GetIDsofNames(即早绑定即早绑定),情况也,情况也许会更好,许

58、会更好,IDL中用中用disinterface支持该类情况支持该类情况u 对象描述语言对象描述语言ODL是对是对IDL的扩充,用来描述的扩充,用来描述COM对象的类对象的类型信息,包括接口的类型信息(型信息,包括接口的类型信息(interface或或disinterface)和)和COM对象类的类型信息(用对象类的类型信息(用coclass关键字描述)关键字描述)u 类型库是类型库是IDL文件经过编译后产生的一个资源文件,包含文件经过编译后产生的一个资源文件,包含COM服务器中服务器中COM对象和接口的信息对象和接口的信息u IDL用用library描述类型库信息,包括类型库的全局唯一标识符描

59、述类型库信息,包括类型库的全局唯一标识符(LIBID)、类型库所使用的版本、语言等)、类型库所使用的版本、语言等COM的动态激活机制的动态激活机制-自动化自动化69COM的动态激活机制的动态激活机制-自动化自动化u 自动化组件可以被脚本语言直接调用,也称为双接口组件自动化组件可以被脚本语言直接调用,也称为双接口组件70u DCOM是是COM的进一步扩展,的进一步扩展,DCOM用网络协议来代替本地用网络协议来代替本地进程之间的通信,并针对分布环境提供了一些新的特性,例如:进程之间的通信,并针对分布环境提供了一些新的特性,例如:位置透明、网络安全性、跨平台调用等位置透明、网络安全性、跨平台调用等u

60、 DCOM的分布特性依靠远程过程调用实现的分布特性依靠远程过程调用实现分布构件对象模型分布构件对象模型DCOM客户机COM运行时环境安全提供者 DCE RPC协议栈COM运行时环境安全提供者 DCE RPC协议栈构件DCOM网络协议网络协议71u基于基于COM组件开发可简要描述为以下几个过程组件开发可简要描述为以下几个过程u建立建立COM组件组件u基于基于ATL编程编程u基于基于MFC编程(编程(可用于实现自动化组件可用于实现自动化组件)u组件的编译组件的编译u组件的注册组件的注册u编写客户端程序,调用组件的接口函数编写客户端程序,调用组件的接口函数基于基于COM组件的开发过程组件的开发过程72组件程序的编译组件程序的编译73u 说明说明1:编译后,类型库以:编译后,类型库以 TLB 文件形式单独存在,同时也文件形式单独存在,同时也保存在目标文件的资源中。保存在目标文件的资源中。 #import 引入类型

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论