基于COM的程序设计原理和应用.docx
《基于COM的程序设计原理和应用.docx》由会员分享,可在线阅读,更多相关《基于COM的程序设计原理和应用.docx(13页珍藏版)》请在冰豆网上搜索。
![基于COM的程序设计原理和应用.docx](https://file1.bdocx.com/fileroot1/2022-12/13/fd3a662b-9fef-45b4-bae8-030e8fc1b4d4/fd3a662b-9fef-45b4-bae8-030e8fc1b4d41.gif)
基于COM的程序设计原理和应用
COM原理及应用----基于COM的程序设计
1、COM的作用
COM作为一种软件模型,提供了程序之间通信的标准,但其最大的贡献在于对程序设计方法的变革。
COM结合了对象技术和组件技术两种特性。
对象特性使得应用系统的设计和实现更加符合现实世界的面貌;组件特性使得应用系统可以充分发挥组件的优势,以适应现代应用的需要。
2、组件的特性
组件之间可以在二进制级别上进行集成和重用;组件必须被独立地生产、获得和配置。
组件接口描述了组件对外提供的服务,组件和组件之间、组件和客户之间同时通过接口进行交互。
组件接口必须是能够自我描述的,组件应该保持接口不变。
3、基于COM的组件化程序设计方法
组件化程序设计方法继承并发展了面向对象程序设计方法。
组件化程序设计方法强调真正的软件重用和高度的互操作性。
4、MTS
MTS,MicrosoftTransactionServer,它为我们提供基本的组件运行和配置环境。
MTS为分布式应用提供了底层的基础设施,它把应用系统的客户程序与应用组件对象以及各种资源有机地组织起来。
在MTS应用中,所有的组件对象都运行在MTS运行环境中,这些组件对象实现了基本的应用逻辑规则。
由于MTS把组件对象有机地管理起来,它的运行环境负责所有并发性处理、资源管理、安全性管理、环境管理等系统级特性处理,因此,开发人员在编写组件对象时可以忽略这些要素,只需简单地实现基本的应用逻辑规则即可。
MTS应用可以包括多个MTS服务进程,每个服务进程运行一个或多个组件对象,所以MTS应用的每个组件对象必须是进程内组件对象,它们运行在MTS服务进程中。
在MTS服务进程中,除了这些应用组件对象之外,MTS也提供了许多服务,包括线程管理服务、环境管理服务、资源分发管理等等。
MTS正是通过这种方式来提供各种系统服务的。
资源管理器是MTS应用管理永久数据的基本手段,它使用了Microsoft的DTC(distributedtransactioncoordinator,分布式事务协调器)系统服务,通过两阶段提交的方式实现了事务(transaction)功能。
MTS实现了两种资源分发器:
ODBC资源分发器和共享属性管理器。
MTS只是一个COM组件对象的管理器,它通过一组内置的服务来简化复杂应用系统的开发。
5、MTS程序设计概念
(1)事务
事务是一个抽象概念,它是指一组数据操作的整体。
事务具有四个特性:
原子性(atomicity)、一致性(consistency)、隔离性(isolation)和永久性(durability),这些特性可简写为ACID。
(2)MTS对象
MTS对象是指运行在MTS环境下的COM组件的一个实例,MTS为每个对象维护一个环境对象。
(3)MTS客户
MTS客户是指MTS对象的客户程序,它可以是一个应用程序,运行在MTS环境之外,这种客户我们称为基客户;MTS客户也可以是另一个MTS对象,所以,MTS客户与对象的概念也是一个相对概念。
(4)安全性控制
MTS推荐使用基于角色的安全模型,角色是MTS安全模型的核心,一个角色定义了用户的逻辑组合。
6、MTS管理程序
MTS管理程序的主要功能为配置和发布MTS对象或组件,MTS对象是指运行在MTS环境中的COM对象,它所在的进程既为MTS服务进程。
在MTS管理程序中,一个基本的概念是MTS包(MTSPackage),MTS包的概念与MTS服务进程紧密相关。
一个MTS包可以包括多个MTS组件,这些MTS组件共享同一个进程,共享同一套安全角色定义。
MTS管理程序使用了标准的MMC管理界面工具。
7、MTS特性
MTS作为COM对象的运行和管理环境,在分布式应用或一般的企业应用中所占的地位越来越重要。
(1)对象管理器
MTS实际上是一个功能强大的对象管理。
MTS使COM对象由统一的环境管理,为基于COM的组件应用系统提供了配置和管理的基础;并且MTS也使DCOM技术的用法更为简化,为建立基于COM分布式应用提供了极大的方便。
MTS还有一个特性,即MTS对象的及时激活(JIT激活,Just-In-TimeActivation)特性
(2)安全管理器
MTS的安全模型可以直接为应用系统所用,利用MTS管理程序用户可以灵活地配置每个角色所对应的成员。
(3)事务管理器
事务特性是MTS环境的一个重要特性,MTS运行环境利用MicrosoftDTC建立起来了事务特性。
8、多层软件结构
COM、DCOM以及MTS构成了多层结构的基础平台。
层与层之间可以通过COM接口联系起来,它们可以运行在不同的进程中,甚至运行在不同的机器上,COM及DCOM提供了进程透明和位置透明特性。
MTS又为中间的业务层提供了统一的配置和管理环境,我们可以把业务逻辑封装到MTS对象中,然后由MTS负责运行和包装这些业务组件。
利用MTS提供的事务特性、安全模型,我们可以简化业务逻辑代码,即使是很复杂的业务逻辑,也可以当作普通的COM组件来实现。
9、多层应用软件结构
在分布式应用系统中,直接面对客户的表现层软件与数据层往往是分离的。
在中间层,MTS可以把所有的业务组件管理起来,并提供运行环境。
10、多层软件结构的优点
可伸缩性、可配置性、灵活性、可靠性、MTS事务和安全模型、跨平台特性和软件集成思想。
11、Web应用基本结构
12、用COM设计Web应用
ASP是服务器一端的脚本环境。
ASP脚本通过Server对象创建COM对象,这种对象称为ActiveServerObject,简称ASP对象。
从完整的ASP应用的角度看,它可以把复杂的业务规则放到ASP组件中,然后在.asp文件中通过脚本代码控制这些ASP对象。
ASP对象既可以直接运行在ASP环境中,也可以运行在MTS环境中,享受MTS环境的特性。
COM原理及应用----COM发展——COM+
1、COM+
由于历史的原因,COM、DCOM和MTS相互之间并不很融洽,难以形成统一的整体。
COM+把这三者有效地统一起来,形成了一个全新的、功能强大的组件体系结构。
COM+并不是COM的新版本,而是COM的新发展,或者COM更高层次上的应用。
COM+的底层结构仍然以COM为基础,它几乎包容了COM的所有内容。
COM+把组件软件提升到应用层而不是底层的软件结构,它通过操作系统的各种支持,使得组件对象模型建立在应用层上,把所有组件的底层细节留给操作系统,因此,COM+与操作系统的结合更加紧密。
COM+不再局限于COM的组件技术,它更加注重于分布式网络应用的设计和实现,已经成为Microsoft系统平台策略的一部分。
2、WindowsDNA策略
WindowsDNA,即DistributedinterNetApplicationArchitecture,分布式网际应用结构。
3、COM+基本结构
COM+提供了一个比MTS更好的组件管理环境,COM+管理程序(COM+Explorer)也采用MMC标准界面。
COM和MTS把组件的所有配置信息都保存在Windows的系统注册表中,而COM+把组件信息保存在被称为COM+目录(COM+Catalog)的新的数据库中。
4、对象环境
COM+为每一个对象提供了一个对象环境(ObjectContext)。
5、COM+系统服务——COM+对列组件
COM客户与远程组件之间的交互是基于RPC连接的。
COM+除了支持这种基于RPC连接的运行方式,还支持基于消息的通信过程,它可以有效地把客户与组件的生存期分离开,这种模式通过COM+的队列组件服务实现。
队列组件采用了底层的消息系统MSMQ(MicrosoftMessageQueueServer,Microsoft消息队列服务系统)。
COM+应用可以以透明方式支持同步和异步两种调用方式。
6、COM+系统服务——COM+事件模型
COM不仅定义了客户调用组件对象的通信过程,也定义了反向的通信过程,这就是COM可连接对象机制。
COM+事件模型改进了COM的可连接对象机制,它采用了多通道的发布/订阅事件机制。
7、COM+系统服务——负载平衡
COM+提供了一个负载平衡服务,它可以以透明方式实现动态负载平衡。
COM+应用程序的负载平衡特性并不需要编写代码来支持,客户程序和组件程序都可以按通常的方式实现。
8、COM+系统服务——内存数据库(IMDB)
COM+的内存数据库(IMDB,inmemorydatabase)服务是一个全新的服务,它用于保存应用的非永久状态信息。
IMDB的功能在于优化数据查询和数据获取,它可以装载后台数据库系统中的数据表,也可以装载应用程序的非永久数据信息。
9、COM+系统服务——其他
事务特性、安全性、COM+对象池和管理服务。
COM原理及应用----ActiveX控件
1、ActiveX控制
ActiveX控制是Microsoft提供的功能强大的程序设计和开发技术。
ActiveX控制既是一个自动化对象(当然也是一个标准的COM对象),也是一个界面元素,如同Windows的普通控制一样。
ActiveX控制是一门综合技术,它涉及到COM和OLE的许多技术精华,同时也与Windows操作系统紧密结合起来,它可作为Windows标准控制的一种扩充机制。
Microsoft把这种在Internet上使用的控制与OCX一起统称为ActiveX控制,并且把所有建立在COM和OLE基础上以及与Internet有关的技术统称为ActiveX技术。
2、ActiveX控制的技术基础
ActiveX控制的主要技术基础为OLE复合文档技术,它几乎涉及OLE嵌入对象与包容器程序之间交互的所有技术,包括结构化存储技术、自动化技术、实地激活(in-placeactivation,主要用于嵌入对象)、属性页技术、永久对象技术、可连接对象机制等等。
3、实地激活
实地激活(in-placeactivation)是指OLE对象的一种界面特性,具有实地激活特性的对象可以直接在包容器窗口内部进行编辑,所以有时我们也把这种特性称作实地编辑(in-placeediting)或可视编辑(visualediting)。
为了实现实地激活特性,要求OLE对象和包容器程序之间必须遵守严格的接口约定。
4、属性页
属性页(propertypage)是OLE的一项技术,它已经成为Windows32位平台上表达属性的基本手段。
属性表(propertysheet)由多个属性页组成,每个属性页有一个标题(也称为标签),通常属性表是一个有模式的对话框,而属性页是一个内嵌在属性表对话框中的无模式窗口。
属性页技术涉及到四个方面:
客户方、COM对象、属性表和属性页。
它们相互之间的通信由一组预定义的COM接口以及API函数实现。
5、属性变化通知
属性变化通知包括两种情形:
第一,当对象改变其属性时,它先向客户发送一个请求,询问客户是否允许改变该属性;第二,当对象已经改变了属性之后,它向客户发送一个通知告诉客户该属性已经被改变。
6、ActiveX控制的基本要求
属性和方法管理、事件机制、用户界面特性(可视性)、状态永久性机制。
7、ActiveX控制基本结构
8、包容器
ActiveX控制的包容器程序通常是一个表单(form)或者对话框,也可以是复合文档的视窗口(view)或文档对象。
包容器通常要管理多个ActiveX控制,或者其他Windows普通控制。
包容器的基本功能:
布局功能、永久特性、环境属性、事件处理机制、扩展控制、键盘功能。
包容器程序支持不同的情形,分别称为设计模式和运行模式。
9、包容器的基本结构
10、使用的接口
IOleObject和IOleClientSite是OLE的基本接口。
每一个嵌入对象必须实现IOleObject接口。
IOleControl和IOleControlSite接口扩展了ActiveX控制与站点对象之间的通信能力。
由于IOleObject和IOleClientSite主要用于OLE复合文档与嵌入对象之间的通信,对于ActiveX控制与包容器,它还有其他的要求,比如环境属性、键盘控制以及扩展控制等等,IOleControl和IOleControlSite接口正是针对这些特性而设计的。
11、ActiveX控制与Internet
Microsoft制定了COM规范,同时又在OLE的基础上形成ActiveX控制标准。
从基本的行为特性来讲,ActiveX控制非常适用于Internet。
从包容器的角度进行考察,Internet浏览器程序就是包容器。
为了使程序代码量尽可能地小,MicrosoftVisualC++提供了ATL模板库作为这类ActiveX控制的基本开发工具。
IE要求ActiveX控制必须支持自注册,以便在用户浏览包含ActiveX控制的Web页面时,它可以动态地注册控制。
一般的包容器程序通常只负责ActiveX控制的创建、运行和释放,但IE要做的事情更多一些。
12、包装ActiveX控制
Microsoft采用了惯用的CAB压缩方法,它把ActiveX控制程序以及相关的其他文件放在同一个CAB文件中,然后在codebase属性中指定CAB文件的URL路径。
13、许可证管理
除了免费发行的ActiveX控制之外,大多数ActiveX控制都支持设计时刻和运行时刻的许可证检查。
设计时刻许可证检查可以保证程序员在创建应用系统或者Web页面时使用合法的ActiveX控制;运行时刻许可证检查可以保证用户运行一个包含合法控制的应用系统或者显示一个包含合法控制的Web页面。
14、ActiveX控制的开发与应用
Microsoft提供了三个开发ActiveX控制的工具:
MFC类库、ATL模板库和BaseControl框架。
MFC重在功能,它与VisualC++集成环境紧密结合,利用MFC可以实现非常复杂的ActiveX控制。
ATL模板库可专门用于开发COM对象,也包括ActiveX控制。
利用ATL,我们可以开发出小巧、快速的ActiveX控制,特别适合于在Internet环境下使用。
BaseControl框架开发ActiveX控制要求程序员对框架结构非常了解,有一定的难度。
COM编程快速入门
1.什么是COM COM是一种跨应用和语言共享二进制代码的方法。
与C++不同,它提倡源代码重用。
ATL便是一个很好的例证。
源码级重用虽然好,但只能用于C++。
它还带来了名字冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。
Windows使用DLLs在二进制级共享代码。
这也是Windows程序运行的关键——重用kernel32.dll,user32.dll等。
但DLLs是针对C接口而写的,它们只能被C或理解C调用规范的语言使用。
由编程语言来负责实现共享代码,而不是由DLLs本身。
这样的话DLLs的使用受到限制。
MFC引入了另外一种MFC扩展DLLs二进制共享机制。
但它的使用仍受限制——只能在MFC程序中使用。
COM通过定义二进制标准解决了这些问题,即COM明确指出二进制模块(DLLs和EXEs)必须被编译成与指定的结构匹配。
这个标准也确切规定了在内存中如何组织COM对象。
COM定义的二进制标准还必须独立于任何编程语言(如C++中的命名修饰)。
一旦满足了这些条件,就可以轻松地从任何编程语言中存取这些模块。
由编译器负责所产生的二进制代码与标准兼容。
这样使后来的人就能更容易地使用这些二进制代码。
在内存中,COM对象的这种标准形式在C++虚函数中偶尔用到,所以这就是为什么许多COM代码使用C++的原因。
但是记住,编写模块所用的语言是无关的,因为结果二进制代码为所有语言可用。
此外,COM不是Win32特有的。
从理论上讲,它可以被移植到Unix或其它操作系统。
但是我好像还从来没有在Windows以外的地方听说过COM。
2.COM所包含的基本元素 接口可以从其它接口继承,这里所说的继承的原理就好像C++中的单继承。
接口是不允许多继承的。
coclass(简称组件对象类——componentobjectclass)被包含在DLL或EXE中,并且包含着一个或者多个接口的代码。
组件对象类(coclasss)实现这些接口。
COM对象在内存中表现为组件对象类(coclasss)的一个实例。
注意COM“类”和C++“类”是不相同的,尽管常常COM类实现的就是一个C++类。
COM服务器是包含了一个或多个coclass的二进制(DLL或EXE)。
注册(Registration)是创建注册表入口的一个过程,告诉Windows操作系统COM服务器放在什么位置。
取消注册(Unregistration)则相反——从注册表删除这些注册入口。
GUID(globallyuniqueidentifier)是个128位的数字。
它是一种独立于COM编程语言的标示方法。
每一个接口和coclass有一个GUID。
因为每一个GUID都是全球唯一的,所以避免了名字冲突(只要你用COMAPI创建它们)。
有时你还会碰到另一个术语UUID(universallyuniqueidentifier)。
UUIDs和GUIDs在实际使用时的用途是一样的。
类ID或者CLSID是命名coclass的GUID。
接口ID或者IID是命名接口的GUID。
在COM中广泛地使用GUID有两个理由:
(1)GUIDs只是简单的数字,任何编程语言都可以对之进行处理。
(2)GUIDs可以在任何机器上被任何人创建,一旦完成创建,它就是唯一的。
因此,COM开发人员可以创建自己特有的GUIDs而不会与其它开发人员所创建的GUIDs有冲突。
这样就消除了集中授权发布GUIDs的必要。
HRESULT是COM用来返回错误和成功代码的整型数字。
除此之外,别无它意,虽然以H作前缀,但没有句柄之意。
下文会对它有更多的讨论。
最后,COM库是在你使用COM时与你交互的操作系统的一部分,它常常指的就是COM本身。
但是为了避免混淆才分开描述的3.COM的基本接口----IUnknown 每一个COM接口都派生于IUnknown。
它的原意是如果有一个指向某COM对象的IUnknown指针,就不用知道潜在的对象是什么,因为每个COM对象都实现IUnknown。
IUnknown有三个方法:
(1)AddRef()–通知COM对象增加它的引用计数。
如果你进行了一次接口指针的拷贝,就必须调用一次这个方法,并且原始的值和拷贝的值两者都要用到。
在本文的例子中没有用到AddRef()方法。
(2)Release()–通知COM对象减少它的引用计数。
(3)QueryInterface()–从COM对象请求一个接口指针。
当coclass实现一个以上的接口时,就要用到这个方法。
当你用CoCreateInstance()创建对象的时候,你得到一个返回的接口指针。
如果这个COM对象实现一个以上的接口(不包括IUnknown),你就必须用QueryInterface()方法来获得任何你需要的附加的接口指针。
QueryInterface()的原型如下:
双击代码全选
1
HRESULTIUnknown:
:
QueryInterface(REFIIDiid,void**ppv);
以下是参数解释:
iid:
所请求的接口的IID。
ppv:
接口指针的地址,QueryInterface()通过这个参数在成功时返回这个接口。
让我们继续外壳链接的例子。
它实现了IShellLink和IPersistFile接口。
如果你已经有一个IShellLink指针,pISL,可以从COM对象请求IPersistFile接口:
双击代码全选
1
2
3
HRESULThr;
IPersistFile*pIPF;
hr=pISL->QueryInterface(IID_IPersistFile,(void**)&pIPF);
然后使用SUCCEEDED宏检查hr的值以确定QueryInterface()的调用情况,如果成功的话你就可以象使用其它接口指针那样使用新的接口指针,pIPF。
但必须记住调用pIPF->Release()通知COM对象已经用完这个接口。
4.COM对象的使用和处理 每一种语言都有其自己处理对象的方式。
例如,C++是在栈中创建对象,或者用new动态分配。
因为COM必须独立于语言,所以COM库为自己提供对象管理例程。
下面是对COM对象管理和C++对象管理所做的一个比较:
(1)创建一个新对象 C++中,用new操作符,或者在栈中创建对象。
COM中,调用COM库中的API。
(2)删除对象 C++中,用delete操作符,或将栈对象踢出。
COM中,所有的对象保持它们自己的引用计数。
调用者必须通知对象什么时候用完这个对象。
当引用计数为零时,COM对象将自己从内存中释放。
由此可见,对象处理的两个阶段:
创建和销毁,缺一不可。
当创建COM对象时要通知COM库使用哪一个接口。
如果这个对象创建成功,COM库返回所请求接口的指针。
然后通过这个指针调用方法,就像使用常规C++对象指针一样。
5.COM对象的创建和删除
(1).COM对象的创建 为了创建COM对象并从这个对象获得接口,须调用COM库的API函数,CoCreateInstance()。
其原型如下:
双击代码全选
1
HRESULTCoCreateInstance(REFCLSIDrclsid,LPUNKNOWNpUnkOuter,DWORDdwClsContext,REFIIDriid,LPVOID* ppv);
以下是参数解释:
rclsid:
coclass的CLSID,例如,可以传递CLSID_ShellLink创建一个COM对象来建立快捷方式。
pUnkOuter:
这个参数只用于COM对象的聚合,利用它向现有的coclass添加新方法。
参数值为null表示不使用聚合。
dwClsContext:
表示所使用COM服务器的种类。
本文使用的是最简单的COM服务器,一个进程内(in-process)DLL,所以传递的参数值为CLSCTX_INPROC_SERVER。
注意这里不要随意使用CLSCTX_ALL(在ATL中,它是个缺省值),因为在没有安装DCOM的Windows95系统上会导致失败。
riid:
请求接口的IID。
例如,可以传递IID_IShellLink获得IShellLink接口指针。
ppv