基于COM的三层应用技术分析_第1页
基于COM的三层应用技术分析_第2页
基于COM的三层应用技术分析_第3页
基于COM的三层应用技术分析_第4页
基于COM的三层应用技术分析_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

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

文档简介

1、基于COM+的三层应用技术分析1. 系统功能11.1系统需求分析11.2小区物业系统的功能模块12. 系统架构22.1两层框架22.2三层架构22.3两层和三层的优缺点33. COM+的由来和演变34. 在delphi中开发COM+组件54.1建立工程54.2编写接口函数64.3注册和安装64.4设置调试65. COM+技术分析75.1概念分析75.2 COM+实现代码分析:85.2.1 GUID8记录类型8接口95.2.4 接口实现类105.2.5 COM+对象生成156. COM+的优缺点186.1COM+的优点186.2COM+的缺点181. 系统功能1.1系统需求分析一个小区的物业,负

2、责整个小区的管理。包含的内容有很多,包括对小区内所有的公共设备和建筑进行管理、维修;对小区内所有的单元户进行信息统计;对小区内的入住人员进行管理;负责小区内的绿化和清洁;查收水电费和物业费;对小区内车辆进行统计,并收取停车费;提供投诉平台,并进行处理;对小区内工作人员进行统计;对外来车辆的管理;对小区内工作人员的工资、休假等管理;设置小区的单位物业费用。1.2小区物业系统的功能模块为了在短期内实现系统,体现开发和使用COM+组件以及三层架构的精髓,将小区物业的管理流程进行简化。系统要实现的模块如图1.1所示。图1.1系统功能模块单元楼模块实现:录入小区内的楼栋信息,包括楼栋名称、高度、一层的房

3、间数、占地面积等。修改小区内的楼栋信息。单元户模块实现:录入小区内的单元户信息,包括所在楼栋、所在高度、房间号、占地面积、名称等。修改单元户的信息,查找单元户信息等。业主模块实现:录入入住人员的基本信息,包括姓名、性别、所在单元户、入住时间、联系电话和身份证号码。修改业主信息、删除业主信息,查找业主信息等。投诉模块实现:录入投诉信息、删除投诉信息、修改投诉信息等。包括投诉时间、投诉人、投诉内容。报修维修模块实现:录入报修记录,包括报修时间、报修内容。并可修改报修记录。录入微机记录,包括维修时间、维修费用,可修改维修记录。系统用户模块实现:添加一个系统用户,包括用户名、登录名、登录密码。可删除和

4、修改选定记录。停车位和车辆模块实现:录入一个车位信息,包括所属楼和车位编号。录入车辆和车主信息,并对车辆和车主信息进行修改、删除、查询操作。添加一个车位的缴费信息。可查看某一个车位的历史缴费记录等。水电费和物业费模块实现:每一个月,录入所有单元户的用电量、用水量、应缴电费、应缴水费、应缴物业费。并可对录入信息进行修改、查询。录入每个单元户的实际缴费记录,并可修改、查询。2. 系统架构2.1两层框架 在数据库开发中,两层框架就是C/S模式。客户机试应用程序,而服务器是数据库服务器。数据库用来存储系统中的数据,而应用程序则负责连接数据库,并担当了显示数据,处理用户输入数据,更新、保存保存数据到数据

5、库的任务。也就是说,客户机承担了数据显示和业务流程的所有任务。而数据显示和整个系统的业务也是融合在一起,没有明显的分界线的。2.2三层架构 三层架构与两层C/S相比,多了一个中间件。中间件也叫做应用程序服务器,中间件负责连接数据库,更新并保存数据到数据库,响应客户端的请求并返回数据等。客户端应用程序不再直接与数据库连接,而是通过中间件关联,并且所有的业务流程和数据处理都放置到中间件中。客户端只用来显示数据,与用户进行交互。2.3两层和三层的优缺点因为两层架构的所有操作都集中到客户端,导致两层架构的客户端比较庞大,并且更新系统要对所有的客户端进行更新,不仅难于维护,维护成本也较高。当系统模块中出

6、现重复的业务逻辑也要进行多次编程,代码复用率较低。但是采用两层架构有利于团队间进行模块化得开发,只要每个人负责一个或者多个模块的数据显示和业务处理。因为三层架构将数据显示和业务逻辑分离,使得客户端比较小,实现了瘦客户机的结构。当每次更新和升级业务处理的时候,都可以只升级服务器端,降低了维护的成本和难度。此外,三层架构将所有的业务逻辑进行集中管理,提高了代码的利用率(相同的业务流程,只需要进行一次编程,在不同的模块中进行调用即可)。但是,与两层架构相比,三层架构的系统也由它的不足之处。三层架构的中间层可以是以dll动态链接库或者EXE可执行程序的形式存在,但不管是哪一种方式,都导致三层框架的系统

7、在编码和调试的时候,更容易出错。三层框架系统的速度和效率也低于两层架构的系统。并且业务逻辑和显示层也不容易分割,容易出现设计问题。Delphi的三层框架技术,也由一定难度,入门到完全掌握需要比较长得时间。3. COM+的由来和演变COM(component object model,组件对象模型)是客户端和COM对象之间进行交流的一种二进制规范。这个规范允许用合适的语言把一些代码编程一个组件,并且允许在编程语言中使用这个组件或功能,即使语言不通,也不会有问题,所以说COM是跨语言的,并且与编程语言无关。COM要实现的就是客户和正在使用的COM对象的透明定位。而所谓的合适的语言是指:COM的跨语

8、言特性是狭隘的。理论上,COM生成的dll动态链接库或者EXE可执行程序可以被任何语言所使用,但是一些非面向对象的编程语言,比如VB,就不能用来创建和使用COM对象。COM除了是一个二进制规范外,还是一种实现。它以一个COM库和一组API函数的形式,提供了创建和管理COM对象的途径。同时,它还可以说是一个服务,它为其他的应用程序提供了COM组件实现的接口函数。无论COM是以进程内(In-Process,dll动态链接库的形式)COM还是以进程外(Out-Process,可执行程序的形式)COM的形式,都只能为本机内的应用程序提供服务,使用COM组件内的接口函数。为了解决COM在分布式上的缺陷,

9、使COM能够在不同的计算机之间进行通信,Microsoft又研发了DCOM。DCOM(分布式COM)是对COM的进一步的扩展,一种无缝的扩充技术。DCOM使COM能够支持在局域网、广域网甚至Internet上不同计算机的对象之间的通讯。DCOM的跨计算机的特性,是因为DCOM封装了网络通讯的底层细节,使开发者致力于应用程序的业务逻辑开发。MTS(Microsoft Transaction Server,事务处理服务),它是Windows NT操作系统推出的一个中间件产品。Microsoft提出这个服务,是为了支出开发企业应用程序中多线程和分布式事务等复杂事务的处理,让windows程序员开发以

10、组件为向导的分布式应用系统。MTS具备在同质和异质数据库之间的数据进行Two phase commit的功能,允许大量的客户端应用程序同时执行,并提供了数据库事务的管理工作。将MTS和DCOM结合起来,很容易的就能开发出一个支持事务处理和多线程、并且保证能够运行在同一台或者不同的机器上的中间件作为一个系统的应用服务器。出现DCOM和MTS之后,开发分布式的系统的基本框架就可以采用如图3.1所示的多层框架。图3.1COM/MTS多层框架虽然MTS的出现,为COM提供了事务处理,安全控制,资源分发控制等服务,为COM开发提供了一个比较完整的系统结构。但是,因为历史的原因,DCOM和MTS的优势还不

11、为windows程序员所认识,DCOM和MTS也不能很好的进行融合。于是,在Windows 2000中,微软引进了COM+的概念。COM+不是对COM的简单升级,它几乎包含了COM所有的功能,并且融合了DCOM和MTS的核心技术。也就说说,COM+不仅可以提供了客户程序和COM+组件之间的透明定位,无论这个客户程序和COM+组件是不是在一个计算机中,同时,COM+也提供了对事务的处理、事件机制、目录和基于角色的安全机制等系统服务。COM+的出现使得开发一个三层框架的系统更加清晰和简单。如图3.2COM+三层框架。图3.2 COM+三层架构4. 在delphi中开发COM+组件4.1建立工程在d

12、elphi的集成开发环境中,提供了创建COM+组件的模板。按照如下的七个步骤就能创建一个COM+组件的框架。1、 打开delphi集成开发工具2、 选择File菜单下的Newother选项3、 在对话框中,选择ActiveX页面4、 选择Transactional Object类型的工程,进行创建5、 在弹出的对话框中,输入Coclass Name。6、 选择线程模式为Aparment(默认)7、 选择事务支持模式为Supports transactional。4.2编写接口函数创建工程后,Delphi集成开发工具会自动创建三个文件。一个工程文件,一个类型库文件,一个COM+接口实现类文件。在

13、delphi中编写COM+组件十分容易,只要打开类型库编辑器,在类型库编辑器中,添加接口、接口函数、枚举类型的变量或者记录类型。在类型库编辑器中所做的操作,都会直接反应到类型库文件中。并且添加的接口函数的实现代码也会添加到实现类文件中。程序员要做的,就是填充实现类中不完整(实际上时没有一行代码的空函数)的函数实现代码,来完成系统的业务流程。4.3注册和安装编写完COM+组件要实现的接口和服务之后,要为其他的应用程序提供服务还需要将COM+组件注册到操作系统中。如果用delphi集成开发环境进行开发,可以选择RUN菜单下的Register ActiveX Server选项,将COM+组件注册到注

14、册表中。此外,还可以运行windows提供的一个程序Regsvr32.exe 来注册组件。接着将COM+组件安装到操作系统的COM+应用程序中。选择RUN菜单下的Install COM+ Objects选项。在对话框中选择一个COM+应用程序,或者创建一个新的COM+应用程序。Delphi开发环境会自动将COM+组件添加到COM+应用程序中。之后,就能够在组件服务中,找到我们开发的这个COM+组件。安装COM+组件还有另外的一种方式就是,打开控制面板,进入管理工具。选择组件服务,并打开COM+应用程序列表。右键通过向导建立一个新的COM+应用程序,并将建立的COM+组件添加到COM+应用程序中

15、去。4.4设置调试在客户端应用程序调用COM+组件接口函数的时候,为方便调试,需要对COM+应用程序和工程进行设置。因为默认情况下,COM+是被自动调用和启动的。设置过程如下:1、 在组件服务的COM+组件中,找到新添加的COM+组件应用程序。2、 设置该COM+应用程序的属性高级页面,选中在调试器中打开,并设置正确的调试路径。3、 设置COM+工程。在Project菜单下,选中Options选项。4、 选中对话框的Link页面。5、 选中EXE and DLL options下的两个选项(include TD32 debug info和include remote debug symbols

16、)。6、 选中Run菜单下的Parameters选项。7、 选中对话框的Local页面。8、 填写Host Application为默认值,填写Parameters为COM+应用程序的GUID值。这样就能进行调试了。5. COM+技术分析5.1概念分析前面出现的概念有:接口、COM+组件,COM+应用程序。这三者之间的联系如图5.1所示:图5.1接口、组件和COM+应用程序也就是说一个COM+组件是由接口构成的,它可以包含多个接口。而一个COM+应用程序可以封装多个COM+组件。5.2 COM+实现代码分析:前面一章节中讲到在创建工程之后,就生成了一个类型库文件,该文件以*_TLB命名。*为工

17、程文件的名称,同时也会生成一个实现接口的类文件称之为实现类文件。在类型库文件中,定义了三个GUID和接口以及自定义的函数和记录类型。而在实现类文件则包含了在类型库文件中定义的所有接口函数的实现代码。 GUIDGUID(Globally Unique Identifier,全球唯一标识符),是一个唯一性的标识符。在类型库文件的一开始,就定义了三个GUID类型的常数。1、 LIBID_Server:代表了唯一的类型库,它是COM+对象实现的类型库的ID2、 IID_Iuptown代表了唯一的接口,是COM+对象的一个接口的ID3、 CLASS_uptown用于将COM+组件注册到注册表或者解除注册

18、的时候起着关键性的作用,是生成COM+对象的重要标识符。记录类型在类型库编辑器中添加一个记录类型,delphi集成开发环境就会在类型库文件中自动添加对记录类型的定义。举例说明,在类型库编辑器中添加一个记录类型的变量并命名为Build,为这个记录添加多个字段并设置每个字段的类型。点击刷新按钮后,在类型库文件中,就能看到刚刚添加的记录类型的定义。Build = packed record b_ID: Int64; b_name: WideString; b_address: WideString; b_high: Int64; b_home: Int64; b_size: Double; b_li

19、ft: WideString;end;首先,这个记录类型与我们在delphi中自己定义的记录类型的区别是,多了一个packed的关键字。在delphi中,为了加快取记录类型变量各个字段的速度,进行了这样的优化:变量都是字节对齐的方式。所以会出现sizeof操作出来的结果和记录类型的变量大小不一样的情况。而packed关键字要求对记录类型进行压缩,也就是说避免了delphi对记录类型的优化。这么做不进节省了空间,更重要的是保证了不同的程序进行通信的时候不出错。正是因为COM+组件允许不同的进程调用它提供的服务(接口函数),该记录除了使用packed进行压缩外,每个变量的类型也与一般的delphi

20、应用程序有区别。比如用WideString代替String或者shortstring类型,用Int64代替Interget类型。事实上,在编写COM+组件的时候,不管是函数或者过程的参数还是记录类型的变量等,所有的对外变量都采用特殊的参数类型。这么做的好处是使得与其他进程进行通信的时候,互相兼容。接口COM+组件的基础就是接口。编写COM+组件最重要也是编写COM+组件中的接口和接口中的函数。那么什么是接口呢?接口类似于delphi中的抽象类。因此不能定义一个接口的实例。但与抽象类的区别是,接口仅仅包含了一组实现不同功能的函数和过程,却不能定义变量。也不能对接口中的函数限定范围。所有的函数和过

21、程都默认是public的,不存在private或者protect等修饰。并且接口是用关键字interface定义的,而不是用class。下面就是一个接口的定义:Iuptown = interface(IDispatch) 'CE8179DC-5579-4C47-BBFF-0CA70D28541E' function ConnectToDB: WideString; safecall; function ExecSQL(const sqlString: WideString): OleVariant; safecall; function DisConnect: WideStri

22、ng; safecall; function InsertToBuild(BuildbRecord: Build; out outString: WideString): Int64; safecall; function InsertToHome(HomeRecord: Home; out outString: WideString): Int64; safecall; function InsertToPeople(PeopleRecord: People; inHomeDate: TDateTime; out outString: WideString): Int64; safecall

23、; function SetParameter(const p_name: WideString; const p_value: WideString; var outString: WideString): Int64; safecall; function InsertToCar(CarRecord: Car; out outString: WideString): Int64; safecall; function UpdateCarUse(CarRecord: Car; out outString: WideString): Int64; safecall; ··&

24、#183;···从接口函数的声明中可以看到,每个函数都有safecall标注。原因是:普通函数都是采用register寄存器调用方式,delphi为register调用方式的函数的参数提供最多三个寄存器,用来提高函数调用的速度,超过三个的参数则采用堆栈方式。并且register调用采用从左到右的顺序对参数进行赋值。而COM接口默认的方法调用时stdcall标准调用,即使全部参数采用堆栈方式的调用形式来保持COM的跨语言兼容性。而COM+组件中的接口,是双重接口。在类型库编辑器中,定义一个函数的时候,所有的函数返回值都默认为HResult。这是自动化对象中所有函数都

25、要符合的一个规则。要创建一个想要有返回值的函数,就将参数定义为out类型,或者将最后一个参数的返回值设定为函数名称,类型为out+Refval类型。采用这种方式定义的函数可以捕捉异常,即使是方法中未被处理的异常,也可以被外套处理并通过HReuslt返回给调用者。在定义COM+组件的时候,要捕捉函数调用的异常,必须使用函数OLECheck进行检查。另外,windows中,标准的调用顺序都是从右到左的。 接口实现类接口只有虚函数,并且不能创建变量。要实现接口的函数,就是生成一个接口的实现类。这个实现类继承了一个对象类(Tobject的派生类),并包含一个或者多个接口。小区物业管理系统的实现类定义如

26、下:Tuptown = class(TMtsAutoObject, Iuptown) private con: TADOConnection; function ConnectToDB: WideString; safecall; function DisConnect: WideString; safecall; protected function ExecSQL(const sqlString: WideString): OleVariant; safecall; function InsertToBuild(BuildbRecord: Build; out outString: Wid

27、eString): Int64; safecall; function InsertToHome(HomeRecord: Home; out outString: WideString): Int64; safecall; function InsertToPeople(PeopleRecord: People; inHomeDate: TDateTime; out outString: WideString): Int64; safecall;······ public procedure initialize; override;

28、destructor Destroy; override;从delphi的集成开发环境中,可以看到小区物业管理系统中COM+组件的接口实现类Tuptown的继承关系如图5.2所示:图5.2实现类的继承关系 父类的含义1、TComObjectTComObject实现了IUnknown、ISupportErrorInfo、标准的COM聚集支持和一个对应的类工厂支持。如果我们想创建一个轻量级的可连接客户端的基于IUnknown接口的COM对象的话,COM对象就应该从TComObject 类继承。 2、TComObjectFactoryTComObjectFactory 是同TComObject对象配

29、合工作的。它把对应的TComObject 公开为CoClass。TComObjectFactory 提供了CoClass的注册功能(根据CLSIDs、线程模式、应用程序ID等)。还实现了IClassFactory 和 IClassFactory2 接口以及标准的COM 对象许可证支持。简单地说如果要想创建TComObject对象,就会同时需要TComObjectFactory对象。3、TTypedComObjectTTypedComObject等于TComObject 和对IProvideClassInfo接口的支持。IProvideClassInfo 是自动化的标准接口用来公开一个对象的类型

30、信息的(比如可获得的名字、方法、支持的接口等,类型信息储存在相关的类型库中)。TTypedComObject 可以用来支持那些在运行时能够浏览类型信息的客户端,比如Visual Basic的TypeName 函数期望一个对象能够实现IProvideClassInfo 接口,以便通过类型信息确定对象的文档名称(documented name)。4、TTypedComObjectFactoryTTypedComObjectFactory 是和TTypedComObject配合工作的。就等于TComObjectFactory + 提供缓存了的TTypedComObject类型信息(ITypeInfo

31、)引用。一句话,创建TTypedComObject必然会同时创建TypedComObjectFactory 类工厂。5、TAutoObjectTAutoObject 等于TTypedComObject+实现IDispatch接口。TAutoObject适用于实现支持自动化控制的COM对象。6、TAutoObjectFactoryTAutoObjectFactory显然是同TAutoObject密不可分的。它等于TTypedComObjectFactory +提供了TAutoObject的接口和连接点事件接口的缓存类型信息 (ITypeInfo)。7、TMtsAutoObjectDelphi帮助

32、文档中,是这么描述TMtsAutoObject类的:TMtsAutoObject是MTS应用程序服务器的MTS对象和接口的装载器。而MTS自动化对象是那些完成了IObjectControl接口的双重接口自动化服务器。MTS自动化对象将MTS的事物处理、安全机制等特性和自动化对象的特征融合在一起。从这段话中,可以看出,所有的MTS对象都是要完成IObjectControl接口的。 IUnknown接口从图中可以看出,所有的接口的祖先都是IUnknown接口。IUnknown是定义在system.pas文件中的一个接口。它的定义如下:type IInterface = interface '

33、;00000000-0000-0000-C000-000000000046' function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall; function _Release: Integer; stdcall; end; IUnknown = IInterface;可以看到,IUnknown接口包含了三个函数。因为接口所有的函数都是公共的虚函数,所以这三个函数都是由IUnknown的派生类来实现的。1、 QueryInterface函数

34、:返回某个COM对象中的接口指针的函数。从图上可以看出,一个类可以继承一个父类和多个接口,并且一个COM对象可以聚合多个内部接口。如果在应用程序中,使用COM对象没有定义或者包含的接口,就会提示接口不存在等错误信息。因此使用一个接口前可以使用QueryInterface函数判断某一个COM对象是否包含了将要使用到的接口。调用该函数的时候,输入参数是某个接口的ID(IID),当该COM对象实现了要查找的接口的时候,就返回数值S_OK(数值0),而如果没有找到该接口,则返回数值E_NOINTERFACE (数值HRESULT($80004002))。2、 _AddRef函数:接口是引用计数的。当客

35、户端从COM对象中获得一个接口时,该函数就增加了一个接口的引用计数。3、 _Release函数:而当客户端释放了接口调用时,该函数释放掉一个了接口的引用计数。这三个函数的实现,定义在类TComObject中。详细如下:TComObject = class(TObject, IUnknown, ISupportErrorInfo) Private······FRefCount: Integer;······ protected IUnknown function IUnknow

36、n.QueryInterface = ObjQueryInterface; function IUnknown._AddRef = ObjAddRef; function IUnknown._Release = ObjRelease; IUnknown methods for other interfaces function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; function _AddRef: Integer; stdcall;function _Release: Integer; stdcall;

37、83;·····Publicfunction ObjAddRef: Integer; virtual; stdcall;function ObjQueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;function ObjRelease: Integer; virtual; stdcall;······需要提到的是,因为聚合的原因,使得一个IUnknown的派生类中,可能包含了同名的接口函数。如果这些接

38、口函数的实现是相同的,就定义一个共同的方法。但如果是不同的实现函数,就需要使用到方法分辨子句。在TComObject类的定义中,function IUnknown.QueryInterface = ObjQueryInterface; function IUnknown._AddRef = ObjAddRef; function IUnknown._Release = ObjRelease;这三条语句就是方法分辨语句。当调用IUnknown的三个函数的时候,实际上是在执行ObjAddRef、ObjRelease、ObjQueryInterface这三个函数。ObjAddRef和ObjRelea

39、se函数共同维护了接口的引用计数变量FRefCount,承担了COM+组件的生存期。这两个函数和变量FRefCount只在控制COM+组件的生存期的时候才有用,其他时候完全没有意义。在delphi编程中,可以不用考虑这两个函数的调用,系统会自动管理FRefCount变量。但是一旦脱离了delphi,就需要程序员自己调用_AddRef 和_Release函数来管理COM+组件的生存期。 创建接口的函数在创建工程的一开始,就输入了一个CoClass name。这个名字,在*_TLB文件末尾出现。Couptown = class class function Create: Iuptown; cla

40、ss function CreateRemote(const MachineName: string): Iuptown; end;用delphi集成开发环境创建的每一个COM+接口,都会有一个对应的CoClass与之对应。这个CoClass是系统自动生成的,用来创建接口的函数。它提供了两个函数,一个用来创建本地COM+组件接口,另一个用来创建远程的COM+组件接口。这两个函数调用了操作系统中的动态链接库函数,并使用olecheck函数来判断是否接口创建成功。详细的内容将在COM+是如何启动的那一章节中讲述。现在需要知道的是,CoClass的两个函数,在COM+对象的创建中,起了关键的作用。

41、COM+对象生成用来创建COM+对象的接口的函数,已经清楚了。那么接口实现类是如何创建并和接口联系在一起的呢?COM+对象的创建和初始化,都在接口实现类文件最后的initialization部分。initialization部分是delphi用于初始化的特殊部分。当程序启动后,会先行调用这部分的代码进行初始化。小区物业管理系统服务器的初始化代码如下:initialization TAutoObjectFactory.Create(ComServer, Tuptown, Class_uptown,ciMultiInstance, tmApartment); ComServer:TComServe

42、r。ComServer是定义在ComServ单元的全局变量。该变量是用来注册和撤销注册COM+服务的对象。 Tuptown是程序员自己创建的接口实现类。 Class_uptown是GUID类型的常量。将COM+注册到注册表的HKEY_CLASSES_ROOT/CLSID目录下,就要用到Class_uptown常量值。 ciMultiInstance是服务器的实例模式。COM+组件服务器,可以有以下三种实例模式,默认为Mulitple Instance方式。1、Internal:供COM对象内部使用,不会响应客户端的请求,只能通过COM对象内部的其他方法建立。2、Single Instance:

43、不论当前系统内部是否存在相同COM对象,都会建立一个新的程序及独立的对象实例。3、Mulitple Instance:如果有多个相同的COM对象,只会建立一个程序,多个COM对象的实例共享公共代码,并拥有自己的数据空间。 tmApartment是COM+服务器的线程模式。COM+服务器的线程模式一下五种:1、Single:仅单线程,处理简单,吞吐量最低;2、Apartment:COM程序多线程,单个COM对象处理请求单线程;3、Free:一个COM对象的多个实例可以同时运行。吞吐量提高的同时,也要求对COM对象进行必要的保护,以避免多个实例冲突;4、Both:同时支持Aartment和Free

44、两种线程模式。5、Neutral:只能在COM+下使用。在这个函数里面,可以看到建立工程的时候所选择的线程模式等服务器特征最终都是以代码的形式控制和实现的。前面已经提到了TAutoObjectFactory类,它是创建TAutoObject类对象的工厂类。TAutoObjectFactory的create函数递归调用了它的父类的工厂类的create函数,并进行初始化。这个函数提供了创建COM+对象所需要的所有的信息。在TComObjectFactory.Create函数中,有这么一句话:ComClassManager.AddObjectFactory(Self)。这个函数的作用,就是将创建的COM+对象加入到COM的管理器中进行管理。 初始化程序又是怎么被调用的呢?客户端调用CoClass的create或者CreateRemote函数用来返回一个COM+对象的接口。

温馨提示

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

评论

0/150

提交评论