COM聚合的实现的处理技巧
- 格式:doc
- 大小:24.50 KB
- 文档页数:1
《中间件技术》实验指导书西南交通大学软件学院2007年3月目录实验一RPC客户与服务器 (1)一、实验目的 (1)二、实验环境 (1)三、实验原理 (1)四、实验内容及步骤 (1)内容: (1)步骤: (1)五、实验注意事项 (1)六、实验报告要求 (1)七、思考题 (2)实验二动态链接库 (2)一、实验目的 (2)二、实验环境 (2)三、实验原理 (2)四、实验内容及步骤 (3)1、创建DLL文件 (3)2、调用DLL (3)五、实验注意事项 (3)六、实验报告要求 (3)七、思考题 (4)实验三COM组件 (4)一、实验目的 (4)二、实验环境 (4)三、实验原理 (4)四、实验内容及步骤 (4)简单Com实现步骤: (4)客户端实现步骤: (5)五、实验注意事项 (5)六、实验报告要求 (5)七、思考题 (5)实验四包容 (5)一、实验目的 (5)二、实验环境 (6)三、实验原理 (6)四、实验内容及步骤 (6)内容 (6)步骤 (6)五、实验注意事项 (6)六、实验报告要求 (6)七、思考题 (7)实验五聚合 (7)一、实验目的 (7)二、实验环境 (7)三、实验原理 (7)四、实验内容及步骤 (8)内容 (8)步骤 (8)五、实验注意事项 (8)六、实验报告要求 (8)七、思考题 (8)实验六CORBA (9)一、实验目的 (9)二、实验环境 (9)三、实验原理 (9)四、实验内容及步骤 (9)五、实验注意事项 (10)六、实验报告要求 (10)七、思考题 (10)实验七RMI (10)一、实验目的 (10)二、实验环境 (10)三、实验原理 (10)四、实验内容及步骤 (11)编写Java RMI的步骤主要包括以下几步 (11)编译和运行该RMI系统主要步骤有: (11)五、实验注意事项 (11)六、实验报告要求 (11)七、思考题 (11)实验八EJB (12)一、实验目的 (12)二、实验环境 (12)三、实验原理 (12)四、实验内容及步骤 (12)1、在eclipse下使用myeclipse创建EJB服务器端程序 (12)2、eclipse下启动JBOSS和发布EJB (13)3、客户端程序 (13)五、实验注意事项 (13)六、实验报告要求 (13)七、思考题 (13)实验一RPC客户与服务器一、实验目的通过编写RPC的客户服务程序,并调用相应的函数,掌握RPC的原理和编写RPC程序的基本方法。
COM接口协议协议名称:COM接口协议一、引言COM(Component Object Model)接口协议是一种用于在不同软件组件之间进行通信和交互的标准协议。
本协议旨在规范COM接口的定义和使用,确保不同组件之间的互操作性和兼容性。
二、定义1. COM接口:COM接口是一组方法和属性的集合,用于定义组件之间的通信规范。
每一个COM接口都有一个惟一的标识符(Interface Identifier)用于标识该接口。
2. COM组件:COM组件是一种可重用的软件模块,可以通过COM接口与其他组件进行通信。
每一个COM组件都有一个惟一的标识符(Class Identifier)用于标识该组件。
三、接口定义1. 接口标识符(Interface Identifier):每一个COM接口都应具有一个惟一的标识符,用于标识该接口。
标识符采用UUID(Universally Unique Identifier)格式,由32个十六进制数字和4个破折号组成。
2. 接口方法(Interface Methods):接口方法定义了组件之间进行通信和交互的具体操作。
每一个接口方法都应具有惟一的名称、参数列表和返回值。
3. 接口属性(Interface Properties):接口属性定义了组件的状态和特性。
每一个接口属性都应具有惟一的名称、数据类型和访问权限。
四、接口使用1. 接口绑定(Interface Binding):组件在使用COM接口之前,需要通过接口绑定的方式获取接口的实例。
接口绑定可以通过编程语言提供的COM库或者COM对象创建函数来实现。
2. 接口调用(Interface Invocation):一旦获取了接口的实例,组件可以通过调用接口方法来实现与其他组件的通信和交互。
接口调用需要传递方法的参数,并处理返回值。
3. 接口释放(Interface Release):当组件再也不需要使用接口时,应该及时释放接口的实例,以避免资源泄漏和内存泄漏问题。
什么是COM,如何使用COM本文的目的是为刚刚接触COM的程序员提供编程指南,并帮助他们理解COM的基本概念。
内容包括COM规范简介,重要的COM术语以及如何重用现有的COM组件。
本文不包括如何编写自己的COM对象和接口。
COM即组件对象模型,是Component Object Model 取前三个字母的缩写,这三个字母在当今Windows的世界中随处可见。
随时涌现出来的大把大把的新技术都以COM为基础。
各种文档中也充斥着诸如COM对象、接口、服务器之类的术语。
因此,对于一个程序员来说,不仅要掌握使用COM的方法,而且还要彻底熟悉COM的所有一切。
本文由浅入深描述COM的内在运行机制,教你如何使用第三方提供的COM 对象(以Windows 外壳组件Shell为例)。
读完本文后,你就能掌握如何使用Windows操作系统中内建的组件和第三方提供的COM对象。
本文假设你精通C++语言。
在例子代码中使用了一点MFC和ATL,如果你不熟悉MFC和ATL也没关系,本文会对这些代码进行完全透彻的解释。
本文包括以下几个部分:COM——到底是什么?——COM标准的要点介绍,它被设计用来解决什么问题基本元素的定义——COM术语以及这些术语的含义使用和处理COM对象——如何创建、使用和销毁COM对象基本接口——描述IUnknown基本接口及其方法掌握串的处理——在COM代码中如何处理串应用COM技术——例子代码,举例说明本文所讨论的所有概念处理HRESULT——HRESULT类型描述,如何监测错误及成功代码COM——到底是什么简单地说,COM是一种跨应用和语言共享二进制代码的方法。
与C++不同,它提倡源代码重用。
ATL便是一个很好的例证。
源码级重用虽然好,但只能用于C++。
它还带来了名字冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。
Windows使用DLLs在二进制级共享代码。
这也是Windows程序运行的关键——重用kernel32.dll, user32.dll等。
COM组件三个最基本的接口类//VC6中使用COM库的三种方法COM组件有三个最基本的接口类,分别是IUnknown、IClassFactory、IDispatch。
COM规范规定任何组件、任何接口都必须从IUnknown继承,IUnknown包含三个函数,分别是QueryInterface、AddRef、Release。
这三个函数是无比重要的,而且它们的排列顺序也是不可改变的。
QueryInterface用于查询组件实现的其它接口,说白了也就是看看这个组件的父类中还有哪些接口类,AddRef用于增加引用计数,Release用于减少引用计数。
引用计数也是COM中的一个非常重要的概念。
大体上简单的说来可以这么理解,COM组件是个DLL,当客户程序要用它时就要把它装到内存里。
另一方面,一个组件也不是只给你一个人用的,可能会有很多个程序同时都要用到它。
但实际上DLL只装载了一次,即内存中只有一个COM组件,那COM组件由谁来释放?由客户程序吗?不可能,因为如果你释放了组件,那别人怎么用,所以只能由COM组件自己来负责。
所以出现了引用计数的概念,COM维持一个计数,记录当前有多少人在用它,每多一次调用计数就加一,少一个客户用它就减一,当最后一个客户释放它的时侯,COM知道已经没有人用它了,它的使用已经结束了,那它就把它自己给释放了。
引用计数是COM编程里非常容易出错的一个地方,但所幸VC的各种各样的类库里已经基本上把AddRef的调用给隐含了,在我的印象里,我编程的时侯还从来没有调用过AddRef,我们只需在适当的时侯调用Release。
至少有两个时侯要记住调用Release,第一个是调用了QueryInterface以后,第二个是调用了任何得到一个接口的指针的函数以后,记住多查MSDN 以确定某个函数内部是否调用了AddRef,如果是的话那调用Release的责任就要归你了。
IUnknown的这三个函数的实现非常规范但也非常烦琐,容易出错,所幸的事我们可能永远也不需要自己来实现它们。
原理基本概念介绍1.什么是COM(Component Object Modal)COM(Component Object Modal)是Microsoft组件对象模型的简称。
是一个说明如何建立可动态交替更新组件的规范。
简单地说,COM是一种跨应用和语言共享二进制代码的方法。
与C++不同,它提倡源代码重用。
A TL便是一个很好的例证。
源码级重用虽然好,但只能用于C++。
它还带来了名字冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。
2 .COM组件COM组件是由以Win32动态链接库(DLL)或可执行文件(EXE)发布的代码所组成。
3.为什么要学习COM传统的软件开发模式:传统的软件应用程序发布以后,使用者想得到更完善的软件或者去掉其中的某些内容,只有等软件提供商发布新的版本以后,使用者的这一梦想才能得以实现。
使用COM组件以后:软件开发人员可以在软件版本发布以后修改或者去掉软件某个不需要部分。
也及应用程序在更高的层次上定制,使得软件更具灵活性、动态性。
是未来应用软件开发的趋势。
4.COM的前身是OLE(Object Linking and Embedding)对象链接与嵌入。
5.组件:如积木一样,具有“块”的概念,可以动态的将他们插入或卸出应用程序。
这就需要两个条件:第一,组件必须动态链接(不因自己的位置改变而改变自身形式);第二,组件必须隐藏内部实现细节(独立与具体编程语言,二进制形式发布)。
每个组件相当于一个黑盒子,对外提供的只是接口(函数)。
如果接口没有发生任何变化时,对组件的修改几乎不会影响应用程序的其它部分。
提供服务的组件称为服务器组件,使用服务的组件称为客户组件。
1.2.完整的COM组件的接口实现实例#include <iostream>#include <objbase.h>using namespace std;void trace(const char * pMsg){cout<<pMsg<<endl;}// 抽象接口1interface InteX{virtual void _stdcall Fx1() = 0;virtual void _stdcall Fx2() = 0;};// 抽象接口2interface InteY{virtual void _stdcall Fy1() = 0;virtual void _stdcall Fy2() = 0;};// 抽象接口实现class CompA:public InteX,public InteY {public://实现接口InteXvirtual void _stdcall Fx1(){cout<<"CompA::Fx1"<<endl;}virtual void _stdcall Fx2(){cout<<"CompA::Fx2"<<endl;}//实现接口InteYvirtual void _stdcall Fy1(){cout<<"CompA::Fy1"<<endl;}virtual void _stdcall Fy2(){cout<<"CompA::Fy2"<<endl;}};// 客户程序int main(){trace("客户:创建组件的一个实例。
COM聚合COM聚合聚合的概念内部组件的实现外部组件的实现A TL7对内部组件的支持分析:DECLARE_CLASSFACTORY()宏-------------DECLARE_AGGREGA TABLE(T)宏---------------------A TL7对外部组件的支持聚合的概念聚合源自组件重用。
当有两个组件A和B,他们分别实现了自己的接口IA和IB。
如果有一个客户程序创建了A对象使得自己可以调用IA的方法,但同时又想获得IB的接口,调用IB的方法。
这时候有两种做法:一种是客户程序创建B对象,还有一种方法是A组件内部创建B组件,然后客户通过某种途径调用B的接口方法。
第一种方法,使得客户必须知道有独立的B组件的存在,第二种方法客户可以认为只有一个组件A,组件A实现了两个接口IA和IB。
第二种方法可以制造出一种假象,让客户程序编写更加简单。
从组件A如何管理组件B的方法上,第二种方法还可以分为两种:包容和聚合。
包容很简单,如果组件IB接口拥有一个方法F(),那么A组件就要实现一个自己的IBEx 接口,并实现IBEx::F( )方法,内部调用IB::F()方法。
这样,客户也就可以通过调用IBEx::F()来调用IB::F。
在这种情况下,客户只知道有IA和IBEx接口,不知道还存在另一个B组件和IB接口。
IBEx::F()增加一些代码从而修改IB::F()方法的功能,甚至可以完全丢弃IB::F()方法。
聚合通常用于IB接口的功能完全不需要做任何的修改,就可以直接交给用户使用的情况。
这时候,如果IB接口的方法很多,包容就显得很笨拙。
因为它不得不对每一个方法作一次包装,尽管什么都不做。
COM+对象池就是通过聚合我们的组件,来把我们组件的接口暴露给客户的。
聚合方式下,A组件直接将IB接口交给客户,客户就可以调用,但是客户仍然以为是A组件实现了IB接口。
如下图:组件AIUnknown组件BIB客户直接使用IA客户直接使用内部组件的实现客户程序只知道A组件而不知道B组件,并且认为A组件实现了IA和IB接口。
COM+原理及应用COM+的结构COM+的底层结构仍然以COM为基础,它几乎包容了COM的所有内容。
有一种说法这样认为,COM+是COM、DCOM和MTS(Microsoft Transaction Server)的集成,这种说法有一定的道理,因为COM+确实综合了这些技术要素。
COM+倡导了一种新的概念,它把COM组件软件提升到应用层而不再是底层的软件结构,它通过操作系统的各种支持,使组件对象模型建立在应用层上,把所有组件的底层细节留给操作系统,因此,COM+与操作系统的结合更加紧密COM+的优点+队列组件COM客户与远程组件之间的交互是基于RPC连接的,客户连接到一个组件对象,请求指定的接口,然后通过接口指针执行同步调用。
虽然COM也允许异步调用,但客户与组件的生存期必须保持一致,调用必须在连接有效期范围内进行。
COM+除了支持这种基于RPC连接的运行方式,它还支持另一种运行模式,我们称为基于消息的通讯过程,它可以有效地把客户与组件的生存期分离开。
这种模式通过COM+的队列组件服务实现,图6是队列组件的基本模型结构。
异步调用:第一,组件的接口成员函数只能有输入参数,不能包含输出参数,这些输入参数将被传递到MSMQ消息中;第二,组件接口成员函数的返回值HRESULT的含义不能与应用相关,它不标识与应用有关的信息。
+事件模型COM不仅定义了客户调用组件对象的通讯过程,它也定义了反向的通讯过程,这就是COM 可连接对象(connectable object)机制。
组件对象定义了出接口(outgoing interface)的所有特征,客户程序实现出接口,当客户程序与对象建立连接之后,客户通过连接点对象建立它与客户端接收器对象之间的反向连接。
实际上,这时的连接点对象成了接收器对象的客户方事件源和客户方紧紧绑定在一起,双方程序代码依赖于出接口的定义,我们必须在编译时刻知道对方的信息;连接点接口的设计模式并没有考虑到分布式环境的特点,所以它在分布式环境下并不很有效COM+事件模型改进了COM的可连接对象机制,它采用了多通道的发布/订阅(multicasting publish/subscribe)事件机制,它允许多个客户去“订阅”事件,这些事件由各种组件对象“发布”。
文章编号:167121742(2004)0320398205COM 原理概述冯正全(成都信息工程学院电子系,四川成都610041) 摘要:组件对象模型(COM )是与平台无关的、分布式的、面向对象的。
COM 是微软OL E ,ActiveX 等的基础技术。
更好的理解COM ,关键是记住COM 不是面向对象的语言,而是创建二进制软件组件的标准。
关 键 词:COM 组件;COM 对象;COM 接口;类厂;COM 库;列集中图分类号:TP313 文献标识码:A收稿日期:2003210213;修订日期:20032122161 引言把一个庞大的应用程序分成多个模块,每一个模块保持功能独立性,在协同工作时,通过相互之间的接口完成实际的任务。
我们把每一个这样的模块称为COM 组件,这些组件可以在不同的计算机上用不同的程序设计语言单独开发,单独编译,单独调试和测试。
当所有的组件开发完成后,把它们组合在一起就得到了完整的应用程序。
2 COM 组件结构在COM 标准中,引入了面向对象的思想,类似与C ++中对象的概念,对象是某个类的一个实例,称为COM 对象。
接口是一组方法的集合,其方法也称为接口成员函数。
COM 组件为COM 对象提供活动空间,COM 对象以COM 接口的方式提供服务。
COM 组件、COM 对象、COM 接口之间的关系如图1所示。
图1 COM 组件、对象、接口关系图每个COM 组件包含多个COM 对象,每个COM 对象提供多个COM 接口供客户使用。
COM 组件有两种,一是进程内组件,是一个DLL (动态连接库)文件;二是进程外组件,是一个EXE (可执行程序)文件。
当另外的组件或普通程序(即组件的客户程序)调用组件的功能时,它首先创建一个COM 对象,然后通过该对象所实现的COM 接口调用它所提供的服务。
组件的内部实现对客户程序是完全隐藏的。
COM 是客户/服务器模型,提供服务的组件是服务器,使用服务的组件和普通程序是客户。
【高阶】聚合链接核心原理和方法
聚合链接是一种通过聚合多个链接或网页来构建一个综合性的导航网站或页面,它可以让用户快速访问相关内容,同时也可以提高网站的品牌知名度和流量。
以下是聚合链接的核心原理和方法:
核心原理:
1. 聚合链接的核心原理是将多个链接或网页整合到一个页面中,使用户可以快速访问相关内容。
这些链接或网页可以是其他网站的主页、产品页面、文章页面等,聚合链接将这些页面整合到一个页面中,使用户可以方便地浏览和访问。
2. 聚合链接可以提高网站的流量和品牌知名度。
通过聚合其他网站的链接,可以吸引用户访问自己的网站,同时也可以提高自己在搜索引擎中的排名,从而增加网站的曝光率和流量。
方法:
1. 手动聚合:手动聚合是指手动收集和整理其他网站的链接,然后将其整合到一个页面中。
这种方法需要花费大量时间和精力,但可以确保链接的质量和准确性。
2. 自动聚合:自动聚合是指通过程序或脚本自动抓取其他网站的链接,并将其整合到一个页面中。
这种方法可以快速地收集大量链接,但需要确保抓取的链接符合法律法规和道德标准。
3. 合作聚合:合作聚合是指与其他网站合作,共同提供相关内容的链接。
这种方法可以增加网站的权威性和可信度,同时也可以与其他网站建立良好的合作关系。
4. 导航网站聚合:导航网站聚合是指将其他网站的链接整合到一个导航网站中,用户可以通过导航网站快速访问相关内容。
这种方法需要建立一个完整的导航网站,同时需要确保链接的质量和准确性。
总之,聚合链接是一种有效的网站推广和品牌建设方法,但需要注意链接的质量和准确性,避免侵犯他人的权益和法律法规。
COM的“可重用性”特性包括两种模型:包容和聚合包容和聚合是COM的两种重用模型,它们的思路基本一致,只是在实现方法上有所不同,下面简要总结一下实现方法:1.包容:假定我们已经实现了一个COM对象,不妨称它为对象A,它实现了接口ISomeIntf,不久之后,考虑到新的需要,我们要实现一个新的COM对象,称它为B,它既要实现接口ISomeIntf,也要实现接口IOtherIntf,而且,ISomeIntf接口所提供的服务与对象A所提供的服务基本一致,于是,我们考虑在实现对象B的过程中重用对象A的功能,只需要实现新添加的功能就可以完成对象B的开发工作。
最简单的想法就是在实现对象B的接口ISomeIntf时调用对象A的相应成员函数,对于对象A来说,它只是当作一个普通的COM对象,而对于对象B来说,虽然它本身是一个COM对象,但它同时也是对象A的客户,因为它调用对象A的功能服务。
对象B不再重复实现对象A已经实现的功能,而是调用对象A的服务来提供对外的功能服务,对于对象B的客户来说,它根本不知道对象A的存在,可以说它是最大的受益者,因为它得到了全面的功能服务。
这样的情形,我们称为对象B包容对象A,或者对象A被对象B包容,可以用下图表示这种包容关系。
包容的模型在实际使用过程可以非常灵活,对象B的成员函数在调用对象A的接口成员之前或者调用返回之后也可以进行其他一些操作,因此,对象B的ISomeIntf接口提供的功能可以超过对象A的接口功能,返回结果也可以不一致。
更有甚者,对象B的接口与对象A的接口不一定相同,对象B和对象A可以只是一个客户和服务程序的关系而客户程序所看到的只是对象B所暴露出来的接口,对象A的创建和释放完全在对象B内部进行。
一般来说,对象A的生存期包含在对象B的生存期之内。
比较简单的做法是在对象B被构造时,同时创建对象A,并保存好对象A的接口指针,以便在对象B的成员函数中使用;当对象B被释放时,它先把对象A释放掉,这样可以完成对象B对对象A的嵌套使用,形成包容对象模型。
{C++} COM 组件多层聚合嵌套原理大四的课还是蛮有意思的,其中有一个COM组件的课,感觉挺有收获,做了一个小Demo,是关于COM聚合的,聚合和包容是COM的基本特征,老师上课没把这俩的关系讲清楚,也不大知道为啥放着简单的包容不用,用聚合写模块。
通过做这个Demo,俺算是理解了。
因为包容只是单向调用接口,也就是从外到内,不能从内到外。
而聚合则是双向调用的,非常的灵活。
下面通过具体的例子说说。
这个小Demo是控制台调用三个动态链接库的,每个链接库中都有一个方法,最外面的库CompB.dll里面是减法运算,聚合CompC.dll里面的乘法,CompC.dll聚合CompA.dll里面的加法。
CompB.dll调用接口是OtherInterf ace,CompC.dll 调用接口是AnyInterface,CompA.dll调用接口是SomeInterface。
CompB内部指针I nner指向CompC,CompC内部指针Inner指向CompA,Outer指针指向CompB,CompA内部指针Outer指针指向CompC,通过这四个指针,可以使接口查询双向传递。
也就是说我可以通过OtherInterf ace拿到CompA的Add方法,也可以通过SomeInterf ace拿到CompB的Minus 方法,调用方式非常灵活。
三个接口无论调用哪一个都可以访问到三个动态链接库中的所有方法。
每一个方法都可以通过不同接口调用,原理也很清晰和简单。
多层聚合调用的中间层dll就需要一对指针指向上层dll和下层dll,就像CompC一样。
实现也不复杂,每个动态链接库都有一个查询接口方法,CompC和CompA通过非委托查询接口,进行调用传递。
初始化过程是这样的,CompB初始化CompC实例,CompC初始化CompA实例。
CompB如果希望调用CompA就必须先初始化CompC,初始化过程也很清晰。
为了模块的灵活性,多写些代码还是值得滴。
COM聚合的实现:
在com聚合和包容的区别中已经阐述了他们的不同,正是由于这些不同,导致COM包容不需要特殊处理,因为包容不仅继承了外部组件的接口,同时继承了内部组件的接口,所以在IID_xxx接口查询的时候,通过对外部THIS指针的转换,可以返回不同的接口,不存在查询不到的接口。
而聚合不同由于存在两个不同的IUNKOWN接口,所以在用内部接口查询外部接口的时候会查询不到,违背了“如果一个接口可以查询到,那么用其他任何接口都可被查询到的原则”。
解决这个问题是通过以下技巧:
问题:
1、通过外部组件接口可以访问内部组件的接口,m_pIY->QueryInterface();
2、问题在于通过内部组件的接口不能访问外部组件,关键原因还在于内部组件没有外部组
件的IUNKOWN指针。
解决办法:
1、所以让内部组件拥有外部组件的IUNKOWN接口就行了,
CoCreateInstance(IUNKOWN* ..)函数的第一个参数就是要聚合用的,如果聚合的话,就传递给内部接口一个外部组件的IUNKOWN指针,这样内部就可以访问外部的接口了。
2、。