您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 企业文化 > 第07讲-COM原理及组件开发
哈尔滨工业大学计算机学院唐好选Email:tanghx@hit.edu.cnCOM组件技术主要内容COM发展历史及其基本原理构件对象模型COM/DCOMCOM构件的开发与应用COM发展历史及其基本原理COM是微软提出的第一个构件模型,源于OLE:ObjectLinkandEmbedding(对象连接与嵌入)OLE1采用DDE(DynamicDataExchange:动态数据交换)技术在不同的程序之间进行通信DDE缺点:建立在Windows消息机制基础上,效率低、稳定性不好、使用不方便COM是为克服上述不足而出现的COM技术的发展COM定义了客户与构件之间互操作的标准,包括规约与实现两个部分规约部分定义了构件之间的通信机制,不依赖于任何特定的语言和操作系统实现部分就是COM库,为COM规约的具体实现提供了核心服务COM仅支持同一台计算机上(Windows操作系统)的互操作,不支持分布式计算环境COM技术的发展将COM技术延伸到分布计算环境,产生了所谓的DCOM(DistributedCOM,分布构件对象模型)用网络协议代替本地进程之间的通信针对分布式环境提供了新特性:位置透明;网络安全性以及跨平台调用等为了满足企业级应用的需求,推出了微软事务服务器(MTS:MicrosoftTransactionServer),把应用系统的客户程序、应用构件和各种资源有机结合起来,为分布式企业应用提供了一种服务器端的构件运行和部署环境COM技术的发展为了使Windows真正成为企业应用平台,微软推出了分布式网络应用体系结构(WindowsDNA:DistributedinterNetApplicationArchitecture),DNA是一个完整的、多层的企业应用体系结构:包含工具、数据库、操作系统、编程模型和应用服务等随着Win2000发布,微软进一步把COM、DCOM、MTS统一起来,形成了真正适合于企业级应用的构件技术:COM+可以认为:COM/DCOM+MTS=COM+COM+是一种中间件技术规约,提供操作系统级的分布式“服务”COM技术的发展WindowDNADNA是一个服务器端的开发平台,包括Windows系统提供运行环境和支持COM/DCOM/COM+MSMQ消息队列产品,支持构件间异步通信MTS管理构件的应用服务MicrosoftWolfpack支持集群服务器的软件MicrosoftSQLServerMicrosoftIISWeb服务器MicrosoftManagementConsole部署和管理工具WindowDNACOM+基本结构COM+目录负载平衡驻留内存数据库对象池新的事件模型构件管理和部署JIT激活COM+MTS事务支持资源分发管理安全模型易于管理远程支持DCOM分布式构件服务COM基于接口的编程模型基本的构件服务COM(ComponentObjectModel),组件对象模型,是一种以组件为发布单元的对象模型,这种模型使得各个软件组件可以用一种统一的方式进行交互COM是一种协议,它建立了一个软件模块同另一个软件模块之间的连接,提供了组件之间进行交互的规范,也提供了实现交互的环境当这种连接建立起来后,两个模块之间就可以通过“接口”的机制来进行通讯,这些接口既不需要静态的或动态的连接入口点,也不需要编码很复杂的地址什么是COM?全局唯一标识符(GlobalUniqueIDentifier)来源于OSF的通用统一标识符UUID(UniversalUniqueIDentifier),是一个128位整数GUID的作用用于标识COM对象(CLSID)和接口(IID)空间足够大,冲突较小,可用编程方法生成唯一GUIDVC:UUIDGEN.EXE,GUIDGEN.EXE对GUID值的传递通常通过引用进行COM基本概念:GUID基本概念:COM对象/COM构件/COM接口COM构件对象1对象2接口1接口2接口3接口4基本概念:COM对象和COM构件COM对象是指符合COM规则的CoClass(构件类)的实例,每一个COM对象都有一个GUID,称为CLSID(CoClassID)COM构件是指以编译后的形式提供一组功能的COM对象独立于具体编程语言一个构件可以由多个类实现以二进制形式(DLL或EXE)发布可以在不妨碍客户的形式下被升级可以透明地在网络上被重新分配COM接口是COM规范的核心内容,是COM对象显示出来的所有信息,是一组逻辑上相关的函数集合每一个接口都有一个GUID,称为接口标识符(简称IID:InterfaceIDentifier)COM接口具有不变性,只允许单继承一个COM对象可以实现多个接口,这体现了COM对象的多态性,这些接口由IUnknown接口来管理在C++中,可以用抽象基类来定义COM接口基本概念:COM接口新版本构件的处理COM接口永远不会变化:一个IID就是一个接口,当对组件进行升级时,一般不会修改已有的接口,而是加入一些新接口当下列条件中的任何一个变化时,应给新接口指定新IID接口中函数数目接口中函数顺序某个函数的参数某个函数参数的顺序某个函数参数的类型函数可能的返回值函数返回值的类型等不同版本接口的命名:在原名称后加一个数字是所有COM对象都必须实现的接口,其它接口都直接或间接继承IUnknown(IID为{00000000-0000-0000-C000-000000000046})接口,包含三个基本操作AddRef:提供生存周期管理功能,增加对象引用计数Release:提供生存周期管理功能,用于释放对象QueryInterface:负责向客户提供接口查询功能基本概念:IUnknown接口IUknown接口的定义,定义在win32SDK中的UNKNWN.h头文件中:interfaceIUnkown{virtualHRESULT_stdcallQueryInterface(constIID&,void**ppv)=0;virtualULONG_stdcallAddRef()=0;virtualULONG_stdcallRelease()=0;}MIDL(MicrosoftInterfaceDefinitionLanguage)是定义COM接口的描述性语言,通过独立于具体编程语言的方式来定义接口,该语言基于OSF分布式计算环境(DCE)远程过程调用(RPC)的接口描述语言IDLCOM规范使用的IDL接口描述语言不仅可用于COM接口,同时还定义了一些常用的数据类型,也可描述自定义的数据结构,对于接口的成员函数,可以指定每个参数的类型、输入输出特性,甚至可支持变长度的数组的描述MIDL支持指针类型,与C/C++类似基本概念:接口定义语言接口定义例:interfaceIDictionary{HRESULTInitialize();HRESULTLoadLibrary([in]string);HRESULTInsertWord([in]string,[in]string);HRESULTDeleteWord([in]string);HRESULTLookWorld([in]string,[out]string*);HRESULTRestoreLibrary([in]string);HRESULTFreeLibrary();}基本概念:接口定义语言COM接口是一个二进制标准,客户同接口的连接并不是通过其名称或其成员函数的名称来实现的,而是通过其在内存块中的位置完成的COM接口是包含一个函数指针数组的内存结构,每一个数组元素包含一个由组件所实现的函数的地址C++通过纯抽象基类实现COM接口,实际上是定义了一个内存块的结构,但此内存只是在派生类中实现此抽象基类时才会被分配,派生类继承此抽象基类时将继承此内存结构COM接口Vtbl指针虚拟函数表pIXIX&Fx1&Fx2&Fx3&Fx4虚拟函数表COM接口的内存结构同C++编译器为抽象基类所生成的内存结构是相同的,对于如下利用纯抽象基类方式定义的接口interfaceIX{virtualvoid_stdcallFx1()=0;virtualvoid_stdcallFx2()=0;virtualvoid_stdcallFx3()=0;virtualvoid_stdcallFx4()=0;}提高接口实现的灵活性,实现抽象基类的类可能会将特定于实例的信息同vtbl一块保存例子:一个实现接口IX的类CA,CA包含2个数据:classCA:publicIX{public:virtualvoid_stdcallFx1(){}virtualvoid_stdcallFx2(){}virtualvoid_stdcallFx3(){}virtualvoid_stdcallFx4(){}doubleData1;doubleData2;}Vtbl的作用Vtbl指针虚拟函数表IX&Fx1&Fx2&Fx3&Fx4Data1Data2pAFx1Fx2Fx3Fx4CA实例数据和vtbl一起保存注意:COM组件决不会访问任何实例数据,在COM中,对一个组件的访问只能通过函数完成,绝不能直接通过变量纯抽象基类只有虚拟函数,没有实例数据两个实例共享同一VtblVtbl指针虚拟函数表&Fx1&Fx2&Fx3&Fx4Data1Data2pA1pA2Fx1Fx2Fx3Fx4CAVtbl指针Data1Data2共享同一VtblVtbl指针虚拟函数表IXQueryInterfaceAddRefRelease&FxpAQueryInterfaceAddRefReleaseFxCA所有COM接口都必须继承IUnknown接口,支持其定义的三个函数,而且必须是接口vtbl的前三个函数Vtbl与Iunknown接口IUnknown*CreateInstance();创建构件时,客户可以使用CreateInstance,而不是newCreateInstance的定义:IUnknown*CreateInstance(){IUnknown*pI=static_castIX*(newfoo);pI-AddRef();returnpI;}IUnknown指针的获取一个COM对象(构件)可以实现多个接口使用QueryInterface查询某个构件是否支持某个特定的接口voidfoo(Iunknown*pI){IX*pIX=NULL;HRESULThr=pI-QueryInterface(IID_IX,(void**)&pIX);If(SUCCEEDED(hr)){pIX-Fx();}}接口查询QueryInterface返回的总是同一个IUnknown指针若客户曾经获取过某个接口,那么它将总能获取此接口客户可以再次获取已经拥有的接口客户可以返回到起始接口若能够从某个接口获取某特定接口,则可以从(该构件的)任意接口获取此接口QueryInterface的实现规则通过函数AddRef与Release实现控制构件的生命期解决内存管理问题使构件能够自己将自己删除使用规则返回接口指针之前调用AddRef;使用完接口之后调用Release;赋值之后调用AddRef;引用计数在什么层次上进行计数:构件?对象?接口?构件构件引用记数对象引用记数对象引用记数对象1对象2接口接口接口接口接口引用记数接口引用记数接口引用记数接口引用记数引用计数的实现方式函数的参数中使用接口指针变量对于输入参数,被调函数不必改变计数对于输出参数,相当于生成了一个新的接口指针变量,因此在返回之前,需要使计数增1对于输入输出参数,参数修改之前计数减1,修改之后计数加1,若参数未被修改,计数不变对于局部接口指针变量,不改变计数对于全局接口指针变量,作为参数传给某函数之前,计数增1,返回之后计数减1,C++类成员变量为接口指针变量时也采用此规则引用计数的更详细的规则
本文标题:第07讲-COM原理及组件开发
链接地址:https://www.777doc.com/doc-2152807 .html