版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第7章 客户程序的C+映射,接口映射 在客户端生成一个代理,代理类向客户程序提供一个定位透明的接口,由IDL定义所生成,每一个IDL接口都会生成一个单独的C+代理类。 (1) 生成的代理类与IDL中定义的接口名相同 (2) 代理类由CORBA:Object继承得到 (3) 代理类提供了一个与IDL中定义的操作相对应的一个同名方法。 (4) 此方法被说明为纯虚拟函数,此代理类是不能被实例化的抽象基类。,客户程序的C+映射,对象引用类型 (1) MyObject-这是一个代理基类 (2) MyObject_ptr-这是一个原始的对象引用类型,类似于C+类的实例指针 (3) MyObject_var
2、可以被作为代理的句柄,它与MyObject_ptr非常相似,只是增加了内存管理。 对象引用的生命周期 (1) 当对象引用进入客户程序的地址空间时,有客户端的ORB代表客户程序创建代理。ORB向客户程序返回一个指向新代理的_ptr引用。 (2) 客户程序可以撤消引用 (3) 客户程序可以创建引用所保存的拷贝。 (4) 客户程序可以创建一个空引用。,删除引用 MyObject_ptr mop=; CORBA:release(mop) 引用拷贝 MyObject_ptr mop1=MYObject:_duplicate(mop);,_ptr引用的语义,代理与_ptr引用的映射 在生成代理类的同时就会
3、生成_ptr引用。_ptr引用必须被当作C+指针来使用。 继承与扩展 _ptr引用是指向相应代理类的C+指针,_ptr支持隐式扩展,即指向派生类的指针可以赋给指向基类的指针。 _ptr引用之间的普通赋值是浅赋值。对引用计数不会产生影响。,紧缩转换 在C+中,拒绝把指向基类的指针赋值给指向派生类的指针。强制转换是错误的。 类型安全的紧缩 可以用_narrow来进行安全的强制类型向下转换,与需要的类型相匹配时,返回非空引用,不匹配则返回空引用。_narrow与C+中的dynamic_cast非常相似,作用相同。,_ptr引用的语义,非法使用_ptr引用 (1) 进行相等或不等的比较 (2) 对引用
4、使用关系运算符: (3) 对引用使用算术运算符 (4) 将_ptr引用转换为void *,或将void *转换为_ptr (5) 不采用_narrow进行向下强制类型转换,,ORB的初始化,1. 用ORB_init来对ORB进行初始化 ORB_ptr ORB_init( int argc是argv中的输入项个数 argv是传递给main的命令行参数向量 orb_identifier是由供应商指定的字符串(缺省情况下为空字符串)。,初始引用,ORB接口包含了两个可以用来创建和获取初始引用的操作 object_to_string 将引用转换为一个可以打印的字符串 string_to_object
5、将字符串转换为对象引用,可以返回任意类型的引用,此操作创建一个新的代理,因此在最后要调用release再次将引用释放。,对象伪接口,伪接口:用PIDL调用的接口,不一定由Object隐式继承,不能作为参数传递给普通接口,不能被动态调用,在接口库中没有定义,有一种不同于普通规则的用于特殊目的的语言映射。 _is_a操作 用来测试对象引用是否支持由仓库id参数所支持的接口。 obj-_is_a(“IDL: 同_narrow相似,都用来测试引用是否支持某个接口。而_is_a不需要在编译时知道接口信息,_narrow需要;_is_a用于DII。,_non_existent 用来测试引用是否标识一个已有
6、的对象。与Ping操作相类似。 Ping操作用来测试与实现的一个对象的服务器程序是否可以联系上。 _non_existent为了作出判断,可能会与实现对象的服务器程序进行联系,并且可能会激活该服务器程序,可以用Ping来进行联系和激活。,对象伪接口,_is_equivalent 用来测试一个引用与另一个引用是否完全一样。如果返回true,则表明两个引用完全相同,返回false,则表示可能相同,也可能不同。此操作必须是高效的,因此只能在本地实现 _hash 用来测试引用集合。如果两个引用返回不同的散列值,则表示引用肯定时不同的 _is_nil 用来测试一个引用是否为空,_var引用,_var引用
7、的映射 _var引用的映射与String_var的映射非常相似。对于每个IDL接口,编译器不仅生成接口类和_ptr类型,而且添加了一个_var类。其中的操作与String_var类似。 用_ptr给_var进行初始化或赋值,是一个浅赋值。 用一个_var对另一个_var进行初始化或赋值,是一个深赋值。 _var引用与扩展 不允许通过其它的_var类型对它们进行隐式的初始化或扩展赋值。必须显式的调用_duplicate。,同时使用_var和_ptr引用 _var引用可以转变为指针引用,因此可以进行从派生_var类到基_ptr类的扩展赋值。此赋值是浅赋值。 篏套在用户定义类型中的引用 引用篏套在用
8、户定义类型内,就需要使用_mgr引用。,参数传递规则,参数传递规则主要是为了考虑位置透明性和高效性来制定的。 位置透明性:相同还是不同地址空间,参数的内存管理规则必须统一。这一条件允许相同的源代码用于被配置在一起的对象和远程对象。在此需要用到某些内存管理规则,如变长度的out参数必须由被调用的函数来分配,并且由调用程序来释放。 高效性:要尽可能避免参数值的拷贝。通过对象引用来调用被配置在同一地址空间的CORBA对象几乎与通过虚拟函数来调用C+对象一样快。在此要求大的数值应该由引用来传递,而不是数值。,定长度类型和变长度类型 定长度类型: 整数类型;浮点数类型;定点数类型;字符类型;boolea
9、n;octet;枚举类型。 变长度类型: string和wstring;对象引用;any类型;序列类型 结构、联合和数组是变长还是定长主要是看他们包含的元素类型。,生成的_out类型 out参数往往采用正式的参数类型typename_out。如long类型的out参数,正式类型为CORBA:Long_out。这是因为对于定长度类型和变长度类型的out参数,所使用的内存管理规则不一样。 对于定长度类型,生成的_out类型只是引用的类型定义。例如,Long_out在CORBA名字空间中定义如下: typedef Long 原因在于内存管理规则。变长度类型由被调用的函数进行内存分配,并且为变长度类型
10、生成的_out类可以确保内存被正确释放。,参数传递规则,简单类型的参数传递 简单类型由数值方式还是引用方式来传递取决于被调用函数是否可以修改参数。 in参数采用值传递的方式,它的值不会改变。 inout和out参数采用引用方式传递,因为在调用过程中可能会修改它的值。Long_out是Long char * s; s=p-name(); string_free(s);,while (!done) op=get_request(); char * s; s=invoke(op); send(s) CORBA:string_free(s); ,char * name() p-invoke(“name
11、”); unsigned len; len=recv_len(); s=string_alloc(len); recv(s); return s; ,char * name() char * s; s=string_dup(); return s; ,Request,Reply,返回一个变长度值远程情况下,Client,Server,变长度参数的内存管理,在变长度类型时,在服务器和客户程序之间关系如下: 接口如下定义: interface Person string name(); 客户程序如下: Person_var p=; char s*; s=p-name(); / CORBA:stri
12、ng_free(s);,当客户程序调用name方法时,它将调用代理对象的一个成员函数。事件的顺序如下: (1) 代理的name成员函数创建一个包含操作名称、对象密钥和操作的in和inout参数(这里没有)的请求。 (2)代理成员函数把请求写到服务器程序的连接中,并立即调用连接中阻塞读取的操作(在此是recv_len)。运行时的客户端程序将阻塞,直到收到服务器程序的应答为止。,(3) 此时,请求将通过网络传输给服务器程序。服务器程序将阻塞在get_request操作中,等待客户端连接收到请求。 (4) 客户程序得到外来请求后将继续执行get_request,通过它来获取操作名与对象密钥。 (5)
13、 运行时的服务器程序调用一个普通的invoke函数,其中的一个参数是操作名。Invoke通过操作名来标识正确的应用程序成员函数,以调用应用程序代码。,变长度参数的内存管理,(6) 现在,控制权移交给服务器端的由应用程序提供的name函数。Name函数通过string_dup来分配和初始化字符串的内存,并且返回指向这个内存缓冲区的指针。 (7) 控制权又移交给服务器端的运行时ORB,并且需要运行时ORB传递一个指向已分配过的字符串的指针。现在,运行时ORB构造一个包含字符串拷贝的应答,并且将这个应答发给客户程序。,变长度参数的内存管理,(8) 服务器端的运行时ORB调用string_free来释
14、放这个字符串。(因为字符串的内容已经发送给了客户程序) (9) 现在,服务器端的运行时ORB已经完成了调度循环中的一次循环,它将再次调用get_request,直到下一个客户请求到来后,才能继续下面的操作。 (10) 同时,应答通过网络传递给客户程序,客户程序将执行recv_len下面的操作。返回值是一个字节计数器,用来表示字符串的长度。,(11) 客户端的运行时ORB调用string_alloc来创建一个包含len字节的缓冲区,并且调用recv,以便将字符串内容读到缓冲区中。 (12) 返回一个指向包含字符串的缓冲区的指针后,客户端的存根将结束。 (13) 现在,控制权移交给使用字符串的应用
15、程序代码,应用程序在最后将通过调用string_free擦字符串释放掉。,变长度参数的内存管理,这里应该注意,客户程序或服务器程序中都没有内存泄漏现象: (1) 在服务器端,应用程序调用string_alloc,框架中生成的代码将在把字符串发送给客户程序后,调用string_free。 (2) 在客户端,生成的存根代码将调用string_alloc,并且向应用程序代码返回一个指向字符串的指针,string_free在应用程序中被调用。,变长度参数的内存管理,Person_var p=; char * s; s=p-name(); string_free(s);,char * name() ch
16、ar * s; s=string_dup(); /Fill string return s; ,返回一个变长度值配置在一起的情况,变长度参数的内存管理,配置在一起的情况下,和前面一样,客户程序调用它的代理的name成员函数。然而,现在对于客户程序的地址空间而言,这个成员函数是本地的,因此没有必要检查所有与网络有关的代码。 注意:配置客户程序与服务器程序时,不需要改变应用程序源代码。最重要的时内存规则没有改变。服务器程序调用string_alloc,客户程序调用string_free,因此这里不会出现内存的泄漏。,远程调用和配置在一起调用的透明性是变长度参数内存管理规则的核心。变长度参数的传递要
17、遵循此规则,用于返回值的规则同样也适用于inout参数和out参数。 注意:在发送端分配一个变长度值,而在接收端将它释放掉。,字符串和宽位字符串的参数传递,in参数作为const char *类型来传递。字符串调用程序进行内存的分配、初始化和释放。 inout参数作为char * 生成的头文件中包含下面的框架类定义: class POA_MyObject;,注意: (1) 只有最外层的作用域名称才使用POA_前缀。 (2) 框架类由PortableServer:ServantBase继承得到, PortableServer:ServantBase是所有框架类共同的基类。 (3) 框架类提供一个
18、与IDL的操作相对应的方法 (4) 此方法被说明为纯虚函数,因此不能实例化抽象基类。 (5) 方法中包含了一个异常说明,这个异常说明用来限制此方法能发送C+异常的类型。CORBA:SystemException基类包含所有框架类的异常说明。,伺服类,为了创建MyObject类型的一个CORBA对象,必须从POA_MyObject类中派生一个伺服类,并且实现所有的纯虚拟方法。 假设编写一个IDL为my_object.idl文件,对此编译。 (1) 建立伺服类时要包含生成的服务器端头文件my_objectS.hh,在my_object.idl文件中包含了接口的定义,包含这个头文件是为了获取POA_
19、MyObject基类的说明。 (2) 伺服类的名称MyObject_impl的选择完全由程序决定,符合习惯,使用_impl后缀。,(3) MyObject_impl类由POA_MyObject框架类继承得到,并且重载了纯虚函数get_value。这就使得MyObject_impl成为一个可以实例化的具体类。 (4) 必须在自己的伺服类中实现所有继承得到的纯虚函数,否则,不允许创建伺服类实例。也可以假如任何对支持伺服类的实现有用的东西。例如:构造函数、析构函数、附加的成员函数,或数据成员等。在实际应用中,很少需要对伺服程序进行复制或赋值,因此建立隐藏伺服程序的拷贝构造函数和缺省的赋值运算符。可以
20、把其放在private:中来实现隐藏。,对象的实体,为了通过MyObject_impl伺服类的一个实例来使CORBA对象具体化,必须创建一个MyObject_impl伺服程序和一个CORBA对象,并把伺服程序注册为CORBA对象的实体。 MyObject_impl servant(42);/创建一个伺服程序实例,在此只是一个C+对象,并没有建立伺服程序和CORBA对象之间的连接。 MyObject_var object=servant._this();/创建一个CORBA对象,用创建的伺服程序来具体化这个对象。,在此调用伺服程序的_this函数过程隐式执行了: (1) 在Root POA下创建
21、一个CORBA对象。 (2) 用Root POA把伺服程序注册为新对象的实现。 (3) 为新对象创建一个对象引用。 (4) 返回新的对象引用。,对象的实体,_this函数由框架类提供。POA_MyObject类中包含了由IDL编译器生成的_this成员函数。 对于任何表示IDL接口A的框架类POA_A,POA_A:_this函数的返回值都是A_ptr,即接口A的C+对象引用类型,因为调用_this的程序负责确保最终会对返回的对象引用调用CORBA:release,在此可以把这个返回值返回给A_var,它将负责释放。,由_this创建的CORBA对象是一个暂态对象。暂态CORBA对象在POA中创
22、建,并且受该POA生命周期的限制。可以用合适的策略来创建伺服程序的POA,_this就能提供这种形式的创建和注册服务。Root POA支持的策略的标准设置已经被显式设计为允许提供这种方式来使用_this。,服务器程序的main函数,在完成服务器应用程序时,必须完成下面这些步骤。 (1) 提供标准的CORBA:ORB_init调用初始化ORB (2) 通过由ORB_init返回的ORB引用调用resolve_initial_references(“RootPOA”),通过resolve_initial_references可以获取几个主要接口的对象引用。这里用它来获取一个指向ORB的Root POA的引用,由此又可以获得Root POA的POAManager引用。激活POAManager可以用来使Root POA在ORB开始监听请求时,马上就开始处理请求。,(3) 创建一个MyObject_impl类型的伺服程序。 (4) 调用伺服程序的this函数来创建一个新的暂态的CORBA对象,并且用该伺服程序把它具体化。然后,把返回的对象引用存储到MyObject_var中,以便当MyObject_var离开作用域,返回的对象引用会自动释放。,(5) 为了使潜在的客户程序可以使用新的CORBA对象的对象引用,把对
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二年级信息技术下册 我的佳作我发表 2教学设计 泰山版
- 2026年教师资格考试小学教育教学知识与能力真题与答案
- 2026年中小学教师资格证笔试仿真题及答案
- 北师版数学三年级下册7《统计》(送教案)
- 2026年眼科白内障手术后护理常规操作考核试卷答案及解析
- 2026年四川省机关事业单位考调、选调工作人员考试(综合应用能力测试)模拟试题及答案
- 二年级数学下册 三 三位数的加减法(三位数减三位数的不退位减法)教案 西师大版
- 会议时间地点变更补充函3篇
- 2025-2026学年与人沟通 教学设计
- 立鸿鹄志筑梦想巢小学主题班会课件
- 小红书2025好势发生营销IP新版图通案
- 玉林市玉州区云森木业家具厂家具生产建设项目环评报告
- 昆明市花卉产业高质量发展三年行动方案(23-25)
- 宣讲员宣讲技巧培训课件
- 中国热带农业科学院院属单位2026年第一批公开招聘工作人员备考题库及一套参考答案详解
- 2026年石油工程师钻井技术方向面试要点与答案解析
- 2026年南昌市政公用集团公开招聘工作人员备考题库及参考答案详解
- 启示录概论课件
- 2025年郑州金水区招聘社区工作者200名(公共基础知识)测试题附答案解析
- 220kV输变电工程建议书
- 小儿消化道出血课件
评论
0/150
提交评论