




已阅读5页,还剩39页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
CORBA Programming with TAO - 1.Start(基本概念)摘要:简要介绍CORBA的基本原理,并解释POA、stub、skeleton、servant等重要概念。一、CORBA及TAO简介CORBA是一个为简化跨平台应用而提出的规范,它独立于网络协议、编程语言和软硬件平台,支持异构的分布式计算环境和不同编程语言间的对象重用。CORBA可以作为不同平台应用间信息传递的中间件,CORBA通过引入经过充分验证的有效的框架结构和通信手段,最大限度地简化了网络通信相关应用的设计与开发,使得我们可以专注于业务逻辑的实现,而无需关心通信的细节。CORBA曾在无数文章中被称作“软总线”,以表明它作为数据传递通道的基本特性。现在存在众多CORBA实现,既有商用的ORBacus、VisiBroker,也有一些优秀的开源实现,如:TAO、omniORB、MICO等。由于各实现遵从相同的规范,接口基本一致,所以在熟练应用一种CORBA实现后,转而使用其它实现时,一般不会存在太大的障碍。TAO(The ACE ORB)是美国华盛顿大学的Douglas C. Schmidt教授领导开发的一个实时CORBA平台,它是一个免费的开放源码项目,用C+语言开发,符合CORBA2.6规范。支持语言: C+支持平台: Win32,常见的各种Unix/Linux,实时操作系统如VxWorks等等。在所有的CORBA实现中,TAO支持的平台是最多的。支持的服务: Naming、Event、Notification、Security、Time、Scheduling、Logging、Lifecycle、Trading、Concurrency、Lifecycle、A/V Streaming、Load balancing等。本系列文章将以当前最新的ACE-5.5+TAO-1.5+CIAO0.5为例,简要介绍如何应用TAO进行CORBA C+编程,其中部分内容(尤其是编译器配置相关的内容)是Windows平台特有的,但其它大多数信息在各平台上都是相同或者类似的。二、基本概念本文不打算深入介绍CORBA相关的理论基础(已有很多书籍、文章讨论了这些内容),但在进入下一主题前,为了便于后续问题的讨论,这里简要介绍一下CORBA的基本原理,并对几个重要的基本概念进行解释,以便为没有相关知识的朋友扫清障碍。下图是CORBA的基本模型:图中除上面那根灰线(有点浅,看不清的请慢慢找,_)以上的两个部分需要我们直接介入外,其他部分基本可以由IDL编译器自动生成或由CORBA实现为我们完成。借助CORBA提供的中间件机制,我们在进行方法调用时,无需考虑被调用对象所在的具体位置,而是像调用一个本地模块的方法一样“直接”与其通信(因此,有些应用中,CORBA也被用于本地进程间通信,以降低各模块间的耦合度,同时也便于系统结构的调整)。上图主要包括以下几个组成部分: Client即客户程序,Client通过调用服务程序提供的接口实现特定功能。 ObjectCORBA Object是一个语言无关的虚拟的实体,它可以由ORB定位,并可被客户程序请求调用,它最终由某种语言来具体实现,从而成为应用程序的一部分。 Servant即实例化的Object,Servant是组成服务程序,具体为Client提供服务的某个运行中(且被注册到OA)的C+/Java(或其他语言)对象。Object与Servant是一对多的关系,一个Object可以被实例化多次,注册到一个或多个OA中为一个或多个Client提供服务,各Servant对应不同的IOR(多个IOR具有相同的Type信息,但唯一标识不同),并且,每个Servant都可以由IOR唯一确定,对于持久Object,该IOR在两次启动同一系统时不会发生变化,除非服务程序所在主机IP或配置信息等发生改变,而对于非持久Object,该IOR在两次启动同一服务程序时,总是变化的(因为其中往往包含一个时间戳)。 Stub即桩,或称存根,Stub负责“假扮”Servant为Client提供一个本地化的接口,并负责与ORB进行交互,完成调用请求的列集(marshaling,即打包)与散集(unmarshaling,即解包)。列集的主要作用是按双方ORB可以识别的方式对需要传递的数据进行格式化,而散集则将收到的数据中还原成上层应用可以理解的内存数据形式,对于远端指针,散集时ORB还负责分配相应的内存空间,并将指针的内容复制到本地内存空间以为本地应用提供一个远端指针的镜像,从而保证本地应用对远端指针的“透明”访问。 Skeleton与Stub对应,负责调用参数在Server端的解包和调用返回的打包。 ORB Core屏蔽底层通信细节的中间件,所有远程访问请求在Client和Server端的ORB间被传递,使得上层应用无需关注平台、语言、网络结构等方面的差异。 Object Adapter(OA)OA是ORB与Servant之间的桥梁,主要负责:1、产生对象引用;2、激活Servant或反之;3、将请求分解后传递给对应的Servant;4、与Skeleton配合完成对Servant提供方法的调用。OA与Servant也是一对多的关系。下面的图形进一步说明了ORB、OA、Skeleton、Servant之间的关系:关于OA的更为详细的信息,详见参考1。三、编译TAOTAO可以从如下地址获得:/Download.html由于TAO是以源码包的形式发布的,因此,获得TAO源码包后,需要自行在所使用的平台上编译TAO。由于下一系列体验CORBA对象模型CCM同样涉及CIAO的编译问题,因此下面将单独用一节内容来介绍如何在Windows平台上编译ACE+TAO+CIAO源码包。参考:1、Irfan Pyarali, Douglas C. Schmidt. An Overview of the CORBA Portable Object Adapter. /schmidt/PDF/POA.pdf2、Michi Henning, Steve Vinoski. Advanced CORBA Programming with C+. Addison-Wesley, 1999.3、Mentoya. TAO使用指南. /ace_tao/tao_guide.htmlCORBA Programming with TAO - 2.Compile Source Code(编译ACE/TAO/CIAO)摘要:简要介绍如何在Windows平台上编译ACE/TAO/CIAO,及编译过程中需注意的问题。正文:随着ACE/TAO/CIAO研究者研究的不断深入,整个平台变得越来越庞大,涉及的工程及目录数目也越来越多,下面简要介绍一下如何在Windows平台上编译ACE/TAO/CIAO,其过程在其它平台上是类似的。一、目录结构在开始之前,先简要介绍一下整个产品的目录结构。ACE(Adaptive Communication Environment)是整个ACE/TAO/CIAO体系的基础,由操作系统适配层、对并发/进程间通信/虚拟内存管理等的OO封装、ACE框架、网络服务组件等几个部分组成;而TAO(The ACE ORB)则是在ACE基础上建立起来的一个CORBA ORB实现;CIAO(Component Integrated ACE ORB)则是在TAO基础上的一个CORBA Component Model实现,同时CIAO也是目前相对比较成熟的一个CCM实现。正是由于三者之间的上述关系,在目录结构上整个源码包也采用了类似下面的结构:ACE_ROOTacedocs.TAO tao docs orbsvcs(TAO实现的众多CORBA服务被放置在这个目录下) . CIAO ciao docs DAnCE RACE .三个产品的帮助文档,可以在相应节点下的docs目录中找到,其中除了对相应产品特定模块或服务的说明外,还包括一些不错的Tutorial,对于我们理解相应产品很有帮助(ACE/TAO/CIAO的较完整的文档是收费的,这些随源码发布的文档虽然少,但仍颇为有用)。二、关于编译器可以使用VC6/7.1/8来编译ACE/TAO/CIAO,不推荐使用VC7,但由于VC6的Project Settings不支持环境变量,会对我们使用CIAO带来一些麻烦(如需手动修改自动生成的工程文件),因此,笔者推荐读者使用VC8,即Visual C+ 2005来进行编译(注:现在VC+ 2005 Express可以从MS的网站上免费获得,但若安装该版本的话,需按照/express/visualc/usingpsdk/default.aspx的指示安装SDK并进行相关设置)。VC8在调试器的设计上有了很大改进,同时对C+标准的支持也有了很大进步(但也变得非常耗资源),因此,下面的讨论将基于ACE-5.5+TAO-1.5+CIAO-0.5 + VC2005 Express,不保证在其它ACE或编译器版本下完全一致。三、基本设置好啦,废话说完了,重新回到我们的主题。首先,设置好如下环境变量:ACE_ROOTTAO_ROOTCIAO_ROOT分别指向ACE根目录,TAO根目录(即%ACE_ROOT%/TAO),CIAO根目录(即%TAO_ROOT%/CIAO)。在%ACE_ROOT%/ace目录下添加一个文件config.h,并在其中添加如下内容:/* -*- C+ -*- */=/* file config.h*/=#define ACE_HAS_STANDARD_CPP_LIBRARY 1#include aceconfig-win32.h若是在其它平台上进行编译,还需要添加文件:$ACE_ROOT/include/makeinclude/platform_macros.GNU具体方法见ACE Installation Guide。此外,为了便于今后使用ACE/TAO/CIAO,应当将%ACE_ROOT%/bin(部分通用工具的输出目录)%ACE_ROOT%/lib(所有.lib、.dll文件的输出目录)添加到PATH环境变量中。并且,需打开VC8,选择Tools - Options - Projects and Solutions - VC+ Directories,添加如下编译器环境变量:Executable files:$(ACE_ROOT)bin$(CIAO_ROOT)binInclude files:$(ACE_ROOT)$(TAO_ROOT)$(TAO_ROOT)orbsvcs$(CIAO_ROOT)$(CIAO_ROOT)ciaoLibrary files:$(ACE_ROOT)lib四、开始编译现在可以开始编译了,但是,在笔者的Win2000中编译ACE5.5/TAO1.5/CIAO0.5时遇到的第一个问题就是:源码包中的VC Workspace/Solution打开之后一片空白,一个工程也没有。(上一版本没有这个问题。最终通过比较源码包中的.sln文件和通过下面的方法得到的.sln文件,发现其实是由于文件是Unix格式造成的)几经周折,终于想到了一个办法:自己运行mwc.pl重新生成工程文件。要运行mwc.pl自然需要安装Perl,安装过程略。下面简单说说mwc的工作原理:mwc.pl根据参数中指定的.mwc文件的内容到相应目录下查找.mpc文件,在没有指定.mwc文件或.mwc文件中没有指定查找目录的情况下会尝试进入各子目录,查找.mpc文件(相当于一个makefile文件),按照.mpc文件生成工程信息,若连一个.mpc文件也找不到,就将当前目录下所有可识别的文件当作源文件,产生一个默认的工程文件。最终,mwc.pl将所有工程文件合并到一个独立的Solution/Workspace。.mwc文件的结构其实很简单,下面是%TAO_ROOT%/TAO_ACE.mwc的全部内容:/ -*- MPC -*-/ TAO_ACE.mwc,v 1.1 2006/02/16 09:20:48 jwillemsen Expworkspace ./ace ./apps/gperf/src ./ACEXML/common ./ACEXML/parser/parser ./ACEXML/apps/svcconf ./Kokyu/Kokyu.mpc ./protocols tao TAO_IDL utils orbsvcs exclude orbsvcs/tests orbsvcs/performance-tests orbsvcs/examples 其作用就是告诉mwc.pl到哪些目录下去查找.mpc文件(若没有指定,则表示应检查所有子目录),而其中的exclude则表示应略过那些目录,如果你愿意,完全可以自己编写.mwc文件(不过,工程具体的描述文件.mpc则比较复杂,一言难尽,想一探究竟的话,最好还是看看MPC的说明文档/schmidt/ACE_wrappers/MPC/USAGE或/MPC/MakeProjectCreator.pdf)。对mwc.pl的工作原理有了基本的了解后,就可以运行mwc.pl生成工程文件了。执行mwc.pl的办法很简单,如要生成使用CIAO的基本工程,可以在%CIAO_ROOT%下运行:mwc.pl -type vc8 CIAO_TAO.mwc上述命令将产生一个名为CIAO_TAO.sln的Solution文件,有了.sln文件,就可以正式进行编译了。应用TAO进行CORBA应用开发,下面的几个工程是必须的: TAO_IDL_EXE(即tao_idl,也就是我们的idl编译器,自然少不了,并且后续工程也需要用到该编译器。该工程依赖于ACE、TAO_IDL_BE、TAO_IDL_FE、gperf等多个工程,编译TAO_IDL_EXE是会自动先编译这几个工程) PortableServer(即POA库,编写CORBA应用程序哪能离得开POA,该工程依赖于ACE、TAO、CodeSet、AnyTypeCode等工程) Naming_Service(即命名服务,这是对于我们开发CORBA应用相当有用的一个基本服务,该工程依赖的其它工程就更多了,就不再一一列举了)而要使用CIAO,则还必须编译%CIAO_ROOT%/DAnCE下的多个工程,这些工程包括: ExecutionManager NodeManager Plan_Launcher NodeApplication这几个工程是部署与配置引擎(Deployment And Configuration Engine,DAnCE)的一部分,负责处理面向组件的应用的部署与配置。由于工程之间存在的复杂依赖关系,你只需编译最后这三个工程,就可以自动完成约30个工程的编译工作。编译完以上工程后,你的%ACE_ROOT%/lib和%ACE_ROOT%/bin下会多出来一些.lib、.dll和.exe文件。作为一个ORB服务,Name_Service.exe被放在其对应的子目录%TAO_ROOT%/orbsvcs/Name_Service下。注:1、为了编译CIAO_XML_Utils,需要安装Xerces-C+ 2.7.0,但/xerces-c/提供的下载采用VC6编译,该版本不能用于VC7及以上版本,如果你用的不是VC6,则需要下载源码重新编译。如果你用的是VC+ 2005 Express,由于没有ATL及MFC,在编译时会遇到一些麻烦,可以在SDK Dirinclude下自行添加一个WINRES.h,在其中添加如下代码(两行,空行是必须的):#include 2、如果要试用CIAO,还需用到cidl编译器cidlc,该工具可以从/cidlc/binary/下载。参考:1. Building and Installing ACE and Its Auxiliary Libraries and Services. /schmidt/ACE_wrappers/ACE-INSTALL.html2. Building and Installing CIAO. /schmidt/ACE_wrappers/TAO/CIAO/CIAO-INSTALL.html3. The Makefile, Project, and Workspace Creator (MPC). /MPC/MakeProjectCreator.pdfCORBA Programming with TAO - 3.IDL Data Type(数据类型与Mapping)摘要:简要介绍TAO支持的IDL数据类型及其C+ Mapping关系。一、简单基本数据类型(Simple Basic Types)TAO支持以下简单基本数据类型(%TAO_ROOT%/tao/Basic_Types.h):IDLC+booleanCORBA:BooleancharCORBA:CharoctetCORBA:OctetshortCORBA:Shortunsigned shortCORBA:UShortlongCORBA:Longunsigned longCORBA:ULonglong longCORBA:LongLongunsigned long longCORBA:ULongLongwcharCORBA:WCharfloatCORBA:FloatdoubleCORBA:Doublelong doubleCORBA:LongDouble以上各简单基本类型对应的C+类型只是对应平台上基本类型的typedef(Java虚拟机之所以能够在各平台上保证统一的数据长度,其实现原理也是如此),但在编写应用程序时,为了保证程序的可移植性,应该总是使用CORBA命名空间中的类型标识。此外,需要注意:在上面的所有类型中,没有我们熟悉的C+基本类型byte(被Octet取代)、int(被Long取代)。二、复杂基本数据类型(Complex Basic Types)除以上简单基本数据类型外,TAO还支持以下复杂基本数据类型:IDLC+stringCORBA:TAO_String_Manager(%TAO_ROOT%/tao/Managed_Types.h)wstringCORBA:TAO_WString_Manager(%TAO_ROOT%/tao/Managed_Types.h)anyCORBA:Any(%TAO_ROOT%/tao/AnyTypeCode/Any.h)其中两种String类型在使用时需要注意:1、应该总是使用TAO提供的(也是CORBA规范规定的)如下字符串操作函数:char * string_alloc(ULong len);char * string_dup(const char *);void string_free(char *);WChar * wstring_alloc(ULong len);WChar * wstring_dup(const WChar *);void wstring_free(WChar *);来进行字符串操作,以提高系统的可移植性。2、(w)string_alloc/(w)string_dup后必须调用(w)string_free来释放分配的资源,为了避免忘记(w)string_free带来的麻烦,有些情况下,我们可以考虑使用String_var类型(String_var是String类对应的智能指针类,除了TAO本身支持的智能指针类型外,tao_idl在生成代码时会自动为每个Object添加一个对应的var类型)。3、(w)string_alloc(n)会分配n+1个字符(不是字节)空间。以下是一个简单的字符串操作的例子:#include #include using namespace std;int main() char * p = CORBA:string_alloc(5); / Allocates 6 bytesstrcpy(p, Hello); / OK, Hello fitscout p endl;CORBA:string_free(p);CORBA:String_var s = CORBA:string_dup(World);cout s.in() endl;return 0;注:如果你在编译该程序时遇到困难,请在阅读完本系列的第五篇文章后再来测试该程序(下同)。CORBA:Any与Windows开发中常用的VARIANT类型相当,可以在其中存入任意其他类型的数据,但Any更具有面向对象的风格。在Windows应用中向VARIANT写入信息时需要先设置写入的数据类型,而从中读出数据时往往需要用switch进行判断,相比之下Any的使用就简单多了,我们可以通过=操作符从Any变量中读出信息。与从VARIANT中解析数据不同的是,由于重载的=操作符返回的是一个表示转换成功或者失败的标志,因此,我们总是使用if.else而不是switch来对解析结果进行判断。下面是一个使用Any的例子:#include #include using namespace std;int main() CORBA:Any a;CORBA:Octet o;CORBA:Long l;a = l) cout Long: l endl; else cout Unknown value. endl;a = CORBA:Any:to_octet(o) cout Octet: o endl; else cout Unknown value. endl;return 0;注:过度使用Any类型将对程序的处理性能造成影响。此外,CORBA规范还规定了一种不太常用的数据类型:CORBA:Fixed,它是一种特殊的浮点类型,在构造fixed类型变量时必须指定两个参数:总位数(不含小数点)与精度,而CORBA:Fixed则提供了多种从其它基本类型构造Fixed类型的方法,你甚至可以从字符串类型构造一个Fixed类型变量。但是,目前TAO尚不支持Fixed类型。三、构造类型(Constructed Types)除了上面的基本类型外,我们还可以在idl中使用struct、sequence、union、array等几种构造类型: structstruct与C语言中的struct基本上是等价的,其中只能包含变量定义,不能定义方法,对定义的变量进行初始化,或定义union型变量。 sequencesequence与STL中的vector比较类似,可以用它来存储相同类型的变量,并且可以“自由”扩充,因此,sequence往往可以在传递“变长”参数时发挥重要作用。经过idl处理,sequence会被映射成相应的类。下面举一个sequence的例子:1、首先,定义如下的idl文件:typedef sequence StrSeq;将其存为strseq.idl,并在控制台下对其进行编译,命令如下:tao_idl -Sc strseq.idl编译后,我们将得到一个名为strseq.h的头文件;2、新建一控制台工程,并在主文件中添加如下代码(注:此例全部代码取自):#include strseqC.h#include using namespace std;int main() const char * values = first, second, third, fourth ;StrSeq myseq; / Create empty sequence/ Create four empty stringsmyseq.length(4);for (CORBA:ULong i = 0; i myseq.length(); i+)myseqi = valuesi; / Deep copy/ Print current contentsfor (CORBA:ULong j = 0; j myseq.length(); j+)cout myseq j = myseqj.in() endl;cout endl;/ Change second element (deallocates second)myseq1 = CORBA:string_dup(second element);/ Truncate to three elementsmyseq.length(3); / Deallocates fourth/ Grow to five elements (add two empty strings)myseq.length(5);/ Initialize appended elementsmyseq3 = CORBA:string_dup(4th);myseq4 = CORBA:string_dup(5th);/ Print contents once morefor (CORBA:ULong k = 0; k myseq.length(); k+)cout myseq k = myseqk.in() endl;return 0; unionidl中的union类型与C+中的union不是等价的,它实际上被映射成了对应的class,同时在使用上与C+中的union也有极大区别。以下面的idl为例:union U switch (char) case L:long long_mem;case c:case C:char char_mem;default:short short_mem;其意义可以解释为:类型U可以用于存放三种类型的值:Long型、Char型、Short型,你可以分别用long_mem、char_mem、short_mem取出这些值。当使用一个Long型变量初始化该union变量时,类型标志为L(或者反过来,当类型标志为L时,可以在其中存放一个Long型的值);当用一个Char型变量初始化该union变量时,类型标志为c或者C;当用一个Short型初始化该union变量时,类型标志为其它值。但是,在使用union类型时需要特别注意:不要尝试将类型标志设置为一种类型(通过_d方法),而用另一种类型去初始化它;或者,反过来,用一种类型去初始化它,然后又尝试将类型标志修改为其它值。下面是一个使用上述idl定义的例子:#include using namespace std;#include int main() U my_u; / my_u is not initialized/ my_u._d(c);my_u.long_mem(99); / Activate long_memassert(my_u._d() = L); / Verify discriminatorassert(my_u.long_mem() = 99); / Verify value/ my_u._d(c);cout my_u.char_mem() endl;注:请自行添加相关头文件。当union中还包括其他变长类型时,情况将变得很复杂,但使用上并没有太大差异,这里就不深入讨论了,感兴趣的朋友可以阅读参考1的相关章节。 arrayarray并不是一个idl所使用的关键字,它表示的是普通定长数组,它被映射成C+代码时也是一个普通的定长数组,因此,其用法比较简单。下面是一个使用array的idl的例子:typedef float FloatArray4;typedef string StrArray1510;struct S string s_mem;long l_mem;typedef S StructArray20;相关测试代码如下:#include using namespace std;int main() FloatArray my_f = 1.0, 2.0, 3.0 ;my_f3 = my_f2;StrArray my_str;my_str00 = CORBA:string_dup(Hello); / Transfers ownershipmy_str01 = my_str00; / Deep copyStructArray my_s;my_s0.s_mem = CORBA:string_dup(World); / Transfers ownershipmy_s0.l_mem = 5;注:请自行添加相关头文件。参考:1. Michi Henning, Steve Vinoski. Advanced CORBA Programming with C+. Addison-Wesley, 1999.2. OMG. C+ Language Mapping, v1.1. /cgi-bin/apps/doc?formal/03-06-03.pdfCORBA Programming with TAO - 4.Basic Functions(常用基本方法解析)摘要:简要介绍CORBA规范定义的几个常用基本方法的功能及应用中需要注意的问题。正文:idl编译器会为每个在idl中声明的interface生成一个对应的代理基类:class InterfaceName;以及两个对象引用类型:InterfaceName_ptr和InterfaceName_var前者是一个指针类型,其定义往往是:typedef InterfaceName* InterfaceName;因此,不作过多讨论。InterfaceName_var则是一个智能指针类,通过使用智能指针类,免去了我们手工维护指针引用计数的工作,大大简化了应用程序的编写。下面重点对代理基类和_var智能指针类中的几个基本方法进行简单说明。一、代理基类中定义的几个基本方法每个代理基类(以及CORBA:Object)都提供如下几个静态方法: _duplicate返回一个参数指针的拷贝(为了免去对象深拷贝所引起的消耗,实际是通过调整引用计数的方法实现的) _nil返回相应接口类型的空引用 _narrow尝试将参数指针转型为目标指针,若转换失败,则返回目标类型的空引用。除了以上静态方法,每个代理类还包括两个方法: _is_a该方法接收一个类型id信息const char *type_id,并返回一个CORBA:Boolean,用于判断某个引用是否是type_id所指示的类型。 _this该方法返回当前对象的拷贝的引用。 _add_ref/_remove_ref用于增加引用计数和减小引用计数,在我们编写接口实现时可能会用到(客户程序中无法使用这两个方法,因为只有Skeleton代码中会生成这两个方法,客户程序代码也没有必要使用这两个方法来维护引用计数)。此外,在CORBA命名空间中还定义了: CORBA:is_nil判断某个ptr是否为空 CORBA:release释放参数对象。而为了比较两个引用是否相同,CORBA:Object中定义了方法: is_equivalent按照CORBA规范,不使用以上基本方法对CORBA对象或对象指针进行比较、类型转换、非空测试等所产生的行为都是未定义的。这几个方法本身比较简单,并且后续的文章中将看到上述各基本方法的使用,这里就先不举例了。二、_var智能指针类中的基本方法按照CORBA规范,每个_var智能指针类都包括如下几个方法: in out inout _retn ptr掌握这几个方法的最简单的方法是学习CORBA:String_var类的实现。CORBA:String_var是CORBA:String类的智能指针类,其中封装了一个char*指针。我们来看看TAO是如何实现这几个方法的(见%TAO_ROOT%/tao/CORBA_String.inl):ACE_INLINE const char *CORBA:String_var:in (void) const return this-ptr_;ACE_INLINE char *&CORBA:String_var:inout (void) return this-ptr_;ACE_INLINE char *&CORBA:String_var:out (void) CORBA:string_free (this-ptr_); this-ptr_ = 0; return this-ptr_;ACE_INLINE char *CORBA:String_var:_retn (void) char *temp = this-ptr_; this-ptr_ = 0; return temp;/ TAO extension.ACE_INLINE char *CORBA:String_var:ptr (void) return this-ptr_;表面看来似乎没有什么值得注意的,只是返回了几个不同类型的指针:in方法返回一个指针(因仅作为传入参数),inout方法返回一个指针的引用(因不仅要作我传入参数,还要通过函数调用修改其内容),out方法同样返回一个指针的引用(因需要通过函数调用修改其内容),inout方法返回一个指针(因仅作为返回参数,不能修改),ptr也返回一个普通指针,同样也不能修改内容。但仔细看一看_retn的实现,你会发现,该方法首先保存了指针的内容,然后将指针清0(这样当String_var被释放时就不会free原来的地址空间),最后将该指针返回。也就是说,通过该方法调用,String_var对象所指向的地址空间的控制权被交给了调用该方法的一方,同样,释放地址空间的工作也应该由调用该方法的一方来完成。而对于out方法,为了保证原指针被安全释放,该方法先释放原来指向的地址空间,并将指针清0,最后返回该指针的引用。因此,被调用的方法内部应负责为该对象分配空间,而释放该空间的工作则是由调用方完成的。其他对象上述方法的实现与String_var在原理上是基本一致的,只是IDL编译器tao_idl在生成stub和skeleton代码时会分别为定长结构体和变长结构体应用不同的类模板,从而生成不同类型的_var类。对于定长结构体,应用的类模板为TAO_Fixed_Var_T,而对于变长结构体,应用的类模板为TAO_Var_Var_T。二者的区别在于对于定长结构体而言,_retn和out方法与inout方法的实现是一样的,没有清0的过程,以下是TAO_Fixed_Var_T模板类中的相关代码:/ Mapping for fixed size.templateACE_INLINE T &TAO_Fixed_Var_T:out (void) return *this-ptr_;templateACE_INLINE TTAO_Fixed_Var_T:_retn (void) return *this-ptr_;关于_var类的更多信息,可参考%TAO_ROOT%/tao/VarOut_T.inl,或:/Doxygen/Current/html/tao/classTAO_Var_Var_T.html/Doxygen/Current/html/tao/classTAO_Fixed_Var_T.html三、典型问题解析上面简单介绍了CORBA编程中常用的几个基本方法,下面在此基础上对内存管理相关的几个问题进行简要分析。 包含变长成员变量的结构体的内存释放问题以下面的idl为例:struct DemoStruct string name_;对于如下的代码:int main() /.DemoStruct_var demo = new DemoStruct;_ = CORBA:string_dup(Hello);/.由于我们使用了_var智能指针类,通过new动态分配的空间会在demo对象被销毁时被释放,但是其中通过CORBA:string_dup为成员变量name_所分配的空间是否会泄漏呢?答案是:不会。这是因为idl文件中结构体的string成员变量经过tao_idl编译后,被映射为TAO_String_Manager,这种类型与String_var基本是一样的,只是String_var不带任何参数的构造函数会将指针ptr_初始化为0,而TAO_String_Manager不带任何参数的构造函数则会将ptr_初始化成一个空字符串,具体可见%TAO_ROOT%/tao/Managed_Types.i及%TAO_ROOT%/tao/CORBA_String.inl。因此,当结构体被释放
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届湖南明德中学高三化学第一学期期中复习检测模拟试题含解析
- 2025年二季度骨科护理技术操作常见并发症理论考试题及答案
- 2025年保健品考试题及答案
- 2026届辽宁省本溪中学化学高三上期末质量检测模拟试题含解析
- 2025年陪诊师模拟考试题库及答案
- 2025年环保保护试题及答案
- 2025年注册验船师资格考试(C级船舶检验专业能力)模拟试题及答案二
- 2025年高级运动营养师实操技能解析与模拟题
- 2025年人力资源管理师专业技能测试题库
- 桃花源记app课件
- 《患者的安全转运》课件
- 市政工程交通导行方案
- 梁的弯曲振动-振动力学课件
- 说专业-物流管理专业
- 用友U8全产品功能介绍
- 医院突发公共卫生事件应急预案
- GMAT数学概念单词
- 三基考试题库3
- 化工安全与环保PPT
- 流体力学的课件
- 《城市管理综合执法问题研究国内外文献综述》4800字
评论
0/150
提交评论