第二部分 corba 的核心 第四章 omg 接口定义语言

36
第第第第 第第第第 CORBA CORBA 第第第 第第第 第第第 第第第 OMG OMG 第第第第第第 第第第第第第 4.2 第第 OMG IDL 第 CORBA 第第第第第第第 第第第第第第第第第第第第第 第第第第第第第第第第第 ,。 第第第第第 第第第第 第第第第第第第第第第第第第第第第第第第第第第第第 一,。 IDL 第第第 IDL 第第第第第 第第第 第第第第第第 第第第第第第第第第第第第第第第第第第 一体。 第第第第第第第第第 API 第第第第第第第第第第 API 第第第第第第第第第第第第 ORB 第第IDL 第第第第第 第第第第第第 第第第 第第第第第第第第 ,,一。 IDL 第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第 、, ID L 第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第 ,。

Upload: akamu

Post on 12-Jan-2016

254 views

Category:

Documents


0 download

DESCRIPTION

第二部分 CORBA 的核心 第四章 OMG 接口定义语言. 4.2 简介 OMG IDL 是 CORBA 的基本抽象机理,它从实现中分离出对象接口。在客户机和服务器程序之间建立起了一个契约,用它来描述在应用程序中需要用到的类型和对象接口。 IDL 定义由一个 IDL 编译器编译一个具体的实现语言。编译器将这些与语言无关的定义翻译成特定语言的类型定义和 API ,开发者使用这些类型和 API 来提供应用程序的功能和与 ORB 交互。 IDL 只描述接口,不描述实现,它是一个纯说明性语言。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

第二部分 第二部分 CORBACORBA 的核心的核心第四章 第四章 OMGOMG 接口定义语言接口定义语言

4.2 简介 OMG IDL 是 CORBA 的基本抽象机理,它从实现中分离出对象接

口。在客户机和服务器程序之间建立起了一个契约,用它来描述在应用程序中需要用到的类型和对象接口。

IDL 定义由一个 IDL 编译器编译一个具体的实现语言。编译器将这些与语言无关的定义翻译成特定语言的类型定义和 API ,开发者使用这些类型和 API 来提供应用程序的功能和与 ORB 交互。

IDL 只描述接口,不描述实现,它是一个纯说明性语言。 IDL 定义把焦点集中在对象接口、其它接口所支持的操作和操作时

所可能引发的异常上, 。 IDL 的大部分内容涉及到数据类型的定义,这些数据用来提供客户机和服务器程序之间的交互。

Page 2: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.3 编译 一个 IDL 编译器生成源文件。源文件必须与应用程序代码一起生成客户

机和服务器的可执行文件,不同的 ORB 可能生成不同文件名和文件数目。

4.3.1 编译 IDL 编译器生成四个 IDL 定义的文件,两个头文件 types.hh 和 serv.hh ,

一个存根文件 stubs.cc 和一个框架文件 skels.cc 。 头文件 types.hh 包含在 IDL 中所有的相应类型的定义 ( 数据类型和接口 ) 。 头文件 serv.hh 包含在 IDL 中所有的相应类型的定义 ( 特指服务器端的 ) 。 存根文件 stubs.cc 提供客户程序发送消息给远程的对象所需要的 API 。 框架文件 skels.cc 中提供一个从这个 ORB 到开发人员所编写的服务器源

代码的上端调用接口,并且提供 ORB 的网络层和应用程序代码之间的连接。

客户机和服务器程序还必须与 ORB 库连接,它提供必要的运行时支持。

Page 3: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言

联邦制的服务器程序提供了一种单一的逻辑服务,它将大量的进程分布在不同的机器上。在这种联邦机制中每个服务器程序实现相同的接口,但是控制着不同的对象。

4.3.2 客户机和服务器的不同开发环境 不同语言或不同 ORB 开发的客户机和服务器程序不能共享任何源

代码或二进制组件。 JAVA 不能包含 C++ 头文件,不能共享不同的 ORB 。

客户用 JAVA 在 ORB(A) 上开发,服务器用 C++ 在 ORB(B) 上开发。客户机和服务器完全独立 ( 开发环境、语言映射和 ORB) 。客户机和服务器程序之间唯一的连接就是 IDL 定义。

Page 4: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言客户和服务器连接如下图

IDLDeveloper

IDLSource

IDL-TO-JavaComplier

ClientDeveloper IDL-TO-C++

Complier

ServerDeveloper

impl.cctypes.hh skels.ccserv.hhstubs.ccstubs.javaapp.java

ServerExecutable

ClinetExecutable

Java ORBRun-Time

Library

C++ ORBRun-Time

Library

ORB AORB B

RPC

不同开发环境下的开发过程

Page 5: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.4 源文件 4.4.1 文件的命名 包含 IDL 定义的源文件的命名必须以 idl 为扩展名。编译器拒绝编

译其它扩展名。对于不区分大小写的 DOS ,扩展名用大小写都可。对于区分大小写的 UNIX ,扩展名必须用小写。

4.4.2 文件格式 IDL 是一种自由的格式语言。允许自由的使用空格、水平和垂直制

表符、换行和换页符,没有规定页面布局和缩进方式。任何文本编辑器都可对其进行编辑。

4.4.3 预处理 IDL 源文件是经过预处理的。预处理作为编译器的一部分来实现,

它也可以是外部的程序。预处理常见的有# include 和# define 等。 4.4.4 定义的顺序 IDL 结构,比如模块、接口或类型定义,顺序可任意,但标识符必

须在使用将说明。

Page 6: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.5 词法规则 4.5.1 注释 IDL 定义允许使用 C++ 和 C 两种形式的注释 /*……………………*/ 和 // 4.5.2 关键字 IDL 中关键字必须用小写字母。三个例外: Object 、 TRUE 和 FA

LSE 4.5.3 标识符 标识符由字母、数字和下划线组成,以字母开头,不能以下划线开

头 (转义标识符 ) 。不能有非英语字母 ( 映射困难 ) 。 标识符是不区分大小写的,但必须以大写字母开头。否则非法。 IDL 允许创建凑巧在某种实现语言中正好是关键字的标识符,编译

器使用前缀来避开这个关键字。入 while加前缀后 _cxx_while 。

Page 7: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.6 基本的 IDL 类型 在 CORBA 中,不一定所有的 IDL 提供的类型在任何语言中都与

要求相符。这就要求实现部分提供与要求的取值范围有任何差别的文档资料。

IDL 中仅仅指定了下线尺寸,而未指定上限。这是为了避免限制那些可能的目标环境和语言。 CORBA 规范对 IDL 基本类型的尺寸和取值范围保留了灵活性。如有些 CPU 体系结构没有 8位字符或16 为整数,在这种 CPU 中,映射的取值范围为大于的类型。

类型 范围 尺寸短整型 -215~215-1 ≥16位长整型 -231~231-1 ≥32位无符号短整型 0~216-1 ≥16位无符号长整型 0~232-1 ≥32位浮点型 IEEE 单精度 ≥32位双精度型 IEEE双精度 ≥ 64位字符型 ISO Latin-1 ≥8位字符串型 ISO Latin-1,expect ASCII NUL 变量长度布尔型 TRUE or FALSE 未指定八进制型 0~255 ≥8位any 运行时可标识的任意类型 变量长度

Page 8: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 在 IDL 中没有指针类型的原因: (1) 指针类型在面向对象的编程中要比在非面向对象的语言用的少。 (2) 某些实现语言不支持指针。 (3) 指针使得 ORB 的软件平台的编组的实现复杂化,并增加了允许

时的开销。 4.6.1 整型 IDL 中没有 int 型,只有 short 和 long 类型。 JAVA 中不支持无符号类型, unsigned short 和 unsigned long 映射为

short 和 int 。 4.6.2 浮点类型 这种类型遵循单精度和双精度浮点表达式的 IEEE 规范。那种语言

不支持应提供差异文档资料。 4.6.3 字符 IDL 字符支持 ISO 的 Latin-1 字符集,它是 ASCII 的超集。这种考虑允许多数欧洲语言使用这 8位字符集。

Page 9: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.6.4 字符串 IDL 字符串支持 ISO 的 Latin-1 字符集,除了 ASCII NUL(0) 以外。 I

DL 字符串可以有界或无界,无界用 string ,有界用 string<100> 。字符串的边界不能包含任何表示结尾的 NUL 字符。 Hello 为 string<5>

4.6.5 布尔量 有两种: TURE 和 FALSE 。 IDL 不要求所有的语言用相同的表达

式和尺寸。 4.6.6 八位字节 IDL 的八位字节 (octet) 类型是一个 8位类型,它保证在地址空间之

间传输这些类型时,表达式不会发生任何改变,这样就确保了任何类型的二进制数据交换,以便在交换时不出现干涉。其它类型在数据进行传输时表达式都容易发生改变。

4.6.4 any 类型 类型 any 是一个通用的包容器类型, any 可做任何类型来用。 any 类型常用于编译时,并不知道需要在客户机和服务器之间实际传输何 种 IDL 类型时用。

Page 10: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.7 用户定义类型 4.7.1 命名类型 用 typedef 来创建一个类的新的名称: typedef short YearType; typedef short TempType;

typedef TempType Tem; //bad style

(1) 使更具有可读性和更易于理解 (2) 不必要创建一个现有类型的别名,而应引入一个不同概念的类型。 4.7.2 枚举类型 IDL 的枚举类型的定义与 C++ 相似。 enum Color {red,green,blue,black,grey} ;

IDL 没有定义序数值如何赋给这些枚举值。 IDL 中只能确保枚举的序数值从左向右递增。连不连续也不一定。

只能发送其本身,发送 red 时不能发送 0 ,只能发送 red 。 ORB收到后在对其进行序数值得转换。

Page 11: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 IDL 的枚举值在封闭的命名域内有效 enum IColor {white,black,grey};

enum IColor {red,black,blue}; //错误,黑色被重新定义 IDL 不允许空的枚举。 4.7.3 结构 IDL 支持包含一个或多个已命名的任意类型成员的结构 struct TimeofDay {……};

结构定义形成了一个名字空间,结构成员的名称在封闭的结构内必须是唯一的。

4.7.4 联合 IDL 的联合与 C++ 有相当大的差异,尤其时在判别上。 IDL 的联合允许多个 case 标记作为一个单独的联合成员并支持一个可选的default 。

Page 12: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 IDL增加了一个鉴别器,用来表示当前哪个成员是活动的。 union ColorCount switch(Color){

case red:

case green:

case blue:

unsigned long num_in_stock;

case black:

float discount;

default:

string order_details;};

联合的类型可以是任何类型,鉴别器类型必须是整数类型 ( 字符、整数、布尔量或枚举类 ) 。不能是 octet 。

在封闭的联合内,成员必须是唯一的。 联合的 default 是可选的,但如果出现,则在鉴别器取值的范围内至少有一个在 case 的标记中未显式使用,否则非法。

case FALSE:……; case TRUE:……; default:……; // 没值为默认

Page 13: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 建议不使用 default 。也不要使用多于一个的 case 标记。 union AgeOpt switch(boolean){

case TURE:

unsigned short age;};

这种联合的方式可用来实现可选值,只要为 TRUE ,类型 AgeOpt的值就包含一个 age 。否则为空。

IDL 不支持可选或缺省参数,但可以用以上的联合来模拟这种函数。 联合常用来模拟重载,通过将若干个成员作为一个参数传递给一个

联合,便可用一个单独的操作来实现用若干独立定义的操作才能完成的操作。

4.7.5 数组 IDL 支持任意元素类型的一维和多维数组。 typedef Color ColorVector[10]; typedef string IData[10][20];

Page 14: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 必须用 typedef 来声明数组类型。 所有数组的维数必须是确定的, IDL 不支持开放式数组。因为 IDL

不支持指针 ( 在 C++ 和 C 中,开放式数组恰好是伪装了的指针 ) 。 IDL 中 并没有明确数组在不同的实现语言中如何被索引。有的语言

为 0 开始,有的语言为 1 开始。因此有时要转换。 实际上,发送数组元素本身比下标更容易实现应用程序和直观。 4.7.6 序列 序列是可变长度的向量,可包含任何元素类型,可有界也可无界。 (1) 一个无界序列可以拥有任意个元素,最多可达你的软件平台的

内存极限。 (2) 一个有界序列可以拥有边界所限定的任何数目的元素。 (3) 有界和无界都可为空。 序列元素本身可是一个序列。 typedef sequence<Numbers> ListNumber;

Page 15: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 IDL 允许创建元素的类型是匿名的序列。 typedef sequence<sequence <long,100> > ListNumber;

此为内联的嵌套的序列。外层序列已被严格的定义 ListNumber 类型,而内层序列 long 是匿名类型。应该避免使用这种匿名类型。

>>被认为是右移运算符,必须在 >> 之间插入空格或一个注释符。 4.7.7 序列与数组 怎样选择使用数组还是序列: (1) 如果需要一个可变长度的列表,则用序列。 (2) 如果元素的数目是固定不变的列表,而且在任何时候他们都存

在,则用数组。 (3) 使用序列来实现递归数据结构。 (4) 使用序列来传递一个稀疏的数组 (sparse Array) 给一个操作,可

提高效率,序列只传递非缺省值的元素,而数组要传全部。

Page 16: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.7.8 递归类型 递归只适用于结构和联合,不论哪种情况,递归都表示为这种不完全类

型 (递归类型 ) 的一个匿名序列。 递归与结构 结构可以包含结构定义上的序列作为数据成员。 struct Node{

long value;

sequence<Node> children;}; 递归与联合 一个递归的序列的必定有一个不完全的结构或联合作为它的元素类型。 union Node switch(Color){

case red: long value;

case blue: struct Colors{Color c1;sequence<Node,1> child;} u_c1;

case black: struct Colors{Color c2;sequence<Node,2> child;} u_c2;};

Page 17: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 多层递归 递归可以扩展到多层。 struct TwoLevel{

string id;

struct Nested{

long value;

sequence<TwoLevel> children;} data;};

这个不完全类型 TwoLevel 上的递归篏套在另一个结构 Nested 中。

Page 18: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 互递归结构 struct Astruct{ long data; sequence<Bstruct,1> nested;//非法, Bstruct 没有定义 }; struct Bstruct{ long data; sequence<Astruct,1> nested;}; 以上定义是错误的,因为在 IDL 中,除了接口外,不允许对任何东西进行提前声明。可以用联合来实现。

enum StructType{A_TYPE,B_TYPE}; union ABunoin switch(StructType){ case A_TYPE: struct AC{ long data; sequence<Abunion,1> nested;} A_m; case B_TYPE: struct BC{long data; sequence<Abunion,1> nested;} B_m; };

Page 19: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.7.9 常量定义和字面值 IDL 允许使用常量定义,其句法与语义与 C++ 一致。 const float PI=3.1415926;

IDL 不允许定义 any 类型的常量和用户定义的复杂类型。 应避免定义一些只是一些毫无价值的别名,而未给这个定义添加任

何值。 Const long ZERO=0;

基本类型的别名也可用来定义常量。 typedef short TempType;const TempType MAX_TEMP=35;

与 C++一样, IDL 完全支持字面值 (Literal) 。例如整型常量可以指定为十进制、八进制和十六进制形式;浮点字面值可表示为 C++ 约定的指数和分数;字符和字符串常量支持标准 C++转义字符。

const long l1=oxaB; const double d1=5.0e-10;

const char c1=‘\n’; const string s1=“hello””world”;

Page 20: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.7.10 常量表达式 IDL 中的运算符与 C++ 类似,但不是所有的都与 C++ 有相同的行为。 算术运算符的语义: 算术运算不支持混合模式的算术运算,也没有显式的转换。这主要

是为了简化 IDL 编译器的实现。 整数表达式通常被看作为 unsigned long 类型。除非表达式中包含一

个负整数,则为 long 。运算结果被强制返回目标类型。如果表达式中的中间值超出了 long 或 unsigned long 的范围,或者运算结果不符合目标类型,那么它的行为就不可预测。

位运算符的语义: 为运算符用于整型表达式。将一个 short 或 unsigned short 数值移 16位,或将一个 long 或 unsigned long 数值移 32位都将导致不定行为。

在 C++ 中,右移一个负数是由实现所定义的行为 ( 符号扩展 ) ,相反,在 IDL 中,右移总是执行一个逻辑移位。

const long ALL_ONES=-1; //0ffffffff const long LHW_MASK=ALL_ONES<<16; //0xffff0000 const long RHW_MASK=ALL_ONES>>16; //0x0000ffff

Page 21: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.8 接口和操作 访问一个接口的某一操作将引起这个 ORB 发送一个消息给相应的

对象实现,同一地址空间,调用于一般函数的调用形式一样;不同地址空间, ORB 运行时发送一个远程过程调用给这个实现。

IDL 接口相当于 C++ 的类; IDL 操作相当于 C++ 的成员函数 IDL 与 C++不同的地方: (1) IDL 接口没有公有、私有或保护部分。接口的每一个部分都是公有的。

(2) IDL 接口没有成员变量。 IDL 不存在成员变量的概念,甚至没有共有成员变量。成员变量用来存储状态,而对象的状态与实现有关。当然可以创建对象来存储状态,并且允许客户机控制这个状态。但客户机必须通过这个接口的对象来实现这一目的,同时,如何改变对象状态的细节是隐藏在它的接口内部。

CORBA 对象相当于 C++ 类的实例。 区别在于: CORBA 对象可以在许多不同的地址空间中被实现。

Page 22: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.8.1 接口语法 IDL 接口形成了一个名字空间,标识符只有在他们封闭的接口的作

用于内才有效,并且要唯一。可以在接口定义内篏套下列结构: (1) 常量项定义 (2) 类型定义 (3) 异常定义 (4)属性定义 (5) 操作定义 注意:不可以将一个接口定义在另一个接口内, IDL 接口不支持篏套。

interface Haystack{…… typedef long Needle;…… void find(in Needle n) raises(Notfound);}; 类型 Needle 用在 find 操作的定义中,它们都定义在同一作用域。

由于这个篏套的定义并没有被隐藏,因此可以通过使用作用域解析运算符 :: ,使用在不同作用域的类型来限定一个标识符名。

interface FeedShed{…… void add(in Haystack s) ;…… boolean find(in Haystack::Needle n) raise(Haystack::NotFound); void hide(in Haystack s,in Haystack::needle n);};

Page 23: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 与 C++ 一样, Haystack::Needle 也可表示为 ::Haystack:Needle(前缀 :: 表示全局变量 )

4.8.2 接口语义和对象引用 可以通过传递 Haystack 的参数给 add 操作,将一个干草堆加到储藏室中。以此说明了:

(1) 接口名在它们的右边变成了类型名。 (2) 接口实例可以作为参数传递。 通过对象引用完成添加,它的语义与 C++ 类实例指针十分相似,

只是对象引用还能指向调用程序地址空间外的对象。与 C++ 指针一样,对象引用是强类型的,对象引用的类型安全性是在编译阶段被强制要求的,与 C++ 一致。

CORBA 定义了一个特殊的空对象引用,可实现“可选项”或“没找到”这类语义。

Page 24: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.8.3 接口通信模型 IDL 操作和属性是定义了对象间的通信通道,在通信通道中所传递

的信息类型只是参数、返回值和操作的异常信息。 使用隐含的通信对象接口有时称为合作接口 (Cooperating Interfaces) 。事实上,合作接口几乎总是由同一进程实现的,用这种隐含的方式将能实现两个对象之间的通信。例如, hide 操作。

4.8.4 操作定义 一个操作定义只是作为一个接口定义的一部分出现的,包括: (1) 一个返回结果的类型 (2) 一个操作名 (3)零个或多个参考声明 方向属性: (1) in 表示参数是由客户发送给服务器的 (2) out 表示参数是由服务器发送给客户的 (3) inout 表示参数由客户初始化后,发送给服务器,服务器程序能够修改参数的值,所以,在操作完成时,客户通过的参数值可能已被服务器程序改变。

Page 25: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 需要方向属性的原因: (1) 方向属性可以提高效率 (双向比单向要有的时间多 ) 。 (2) 方向属性可节省传输费用。 (3) 方向属性决定了内存的管理责任。它决定是由客户还是由服务

器来负责参数的内存分配与释放。 定义风格: (1) 如果接口操作接收一个和多个参数并返回一个结果,那么结果

应作为返回值。 (2) 如果操作有若干个同样重要的返回值,所有值都应当作为 out参数返回,并且操作的返回值的类型应为 out 。

(3) 如果操作需要返回若干个值,但有一个是特别重要的,将这个值作为返回值,其它值作为 out参数返回。

这种类型的交互主要用于迭代器操作。 boolean get_next(out ValueType value); 递增检索一个结果的集合,每次检索一个值,返回值是 boolean 。

它只是表示什么时候这些值的集合已经到头了。 while(get_next(val)){ //process val }

Page 26: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 inout参数 使用 inout参数时,接口的设计者假定,调用程序从不想保持原始值并且可以将它们重写。因此, inout参数必须遵循这条原则,即如果客户程序想保持原始值,它必须首先做一分拷贝。

inout参数唯一节省的是所需要的临时缓存空间的数量,因客户和服务器程序只需要单个内存空间来保存调用之前和调用之后的这些数据。

重载 在 IDL 接口内,操作名必须是唯一的,因此操作不可能重载。 匿名类型 在 IDL 中,参数和返回值必须使用一个已命名的类型来声明常量操

作。匿名类型作为返回值及在参数声明中是非法的。 常量操作 在 IDL 中并不区分是读还是访问操作。 SomeType read_value() const; //错误,非法的静态变量应用

Page 27: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 4.9 用户异常 IDL 用户异常定义于 IDL 结构相似,并允许异常包含任

意类型出错信息,且不限定它的数量,但不允许篏套。 异常创建一个名字空间,异常成员名在此名字空间内必

须唯一。 异常是类型,但是不能用来作为用户定义类型的数据成

员。 一个操作使用一个 raise 表达式来表示它可能出现的异

常。 一个操作可能出现多种异常类型,操作必须表示它们可

能出现的所有异常,对一个操作来说,发送一个 raise表达式中没有被列入的用户异常是非法的。

raises 表达式不能是空的。 IDL 不支持异常的继承。

Page 28: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言

4.9.1 异常设计问题 (1) raises 异常只用于异常的状态 ( 不能是结果 ) 。 (2) 要确保异常镌带有用的信息。 (3) 要确保异常传递准确信息。 (4) 要确保异常带有完整信息。 (5) 在设计接口时,应更多的考虑调用者的需要,而不是实现者的

需要。 (6) 一般不要使用返回值和参数来表示出错。 4.10 系统异常 IDL 调用了 29 种系统异常,名称不同,但使用同一异常模块。 enum completion_status{ COMPLETED_YES, COMPLETED_NO, COMPLETED_MAYB

E}; #define SYSEX(NAME) exception NAME{\ unsigned long minor;\ completion_status completed;\}

Page 29: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言

OMGOMG 接口定义语言接口定义语言 操作定义在它的 raises 表达式种不能包括系统异常。 (1) COMPLETED_YES 。错误有时出现在服务器操作完成之后。也

就是说,已经发生了由于错误调用所产生的任何状态变化。 操作不是幂等的话 (idempotent), 了解是否在服务器端完成了操作

是非常重要的。两次调用与一次调用作用相同,就是幂等。 X=1 是幂等, x= x+ 1 不是幂等。

(2) COMPLETED_NO 。错误也可能发生在出客户机地址空间和在进服务器地址空间时出现。这就保证了目标操作并没有被调用,或者已经被调用了,但操作的两端都没有产生作用。

(3) COMPLETED_MAYBE 。完成的状态不确定,客户已调用,可与服务器失去了连接,而调用仍处于连接状态。

minor 数据成员用来传递有关出错代码的附加信息,可未给出含义。 4.11 系统异常或用户异常 服务器上的操作实现可能引发系统异常,以及在操作的 raises 表达

式中的用户异常。 对应用程序级的出错状况定义合适的用户异常。

Page 30: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 31: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 32: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 33: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 34: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 35: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言
Page 36: 第二部分   CORBA 的核心 第四章   OMG 接口定义语言