1、什么是leave ?
因为symbian OS运行在手持设备上,资源有限并且要求长时间无故障运行。所以Symbian的资源管理方法和传统PC有很大不同。如果Symbian OS 应用程序的函数由于某些原因导致失败,超出了程序员的控制(比如:试图打开一个不存在的文件),这个时候函数就有可能leave。在Symbian OS中,对函数来说,leave和传统的C++和java中的抛出异常类似(throwing anexception)。
| A "Leave" causes execution of the active function to terminate, and on through all calling functions, until the first function is found that contains a TRAP() or TRAPD() macro |
“Leave” 可以使函数终止并回退,直到找到第一个包含宏 TRAP() 或 TRAPD()的函数为止。
2、Symbian OS的异常处理
Symbian OS不使用传统的C++类型的异常处理机制(如:try,catch和throw),而是有自己的处理机制:
?Trap 和TrapD,这样允许代码运行在trap harness之中。
?使用User::Leave()显式地说明异常的处理。通常,所有直接或者间接地产生Leave的函数,名字都有一个L后缀。
2.1使用Trap和TrapD
使用Trap和TrapD是定义了一个当函数发生leave时可以返回的代码点(point in code)。其不同的宏定义如下所示:
Trap
| TRAP(_r,_s) {TTrap __t; if (__t.Trap(_r)==0) {_s;TTrap::UnTrap();} } |
TrapD
| TRAPD(_r,_s) TInt _r; {TTrap __t; if (__t.Trap(_r)==0) {_s;TTrap::UnTrap();} } |
可以看出TrapD仅仅是比Trap多定义了一个error code的变量。如果代码段_S发生了leave,那么错误代码存放在_r中,否则,_r的值为KErrNone。对于_S来说,通常为一个函数调用不同的用法如下所示:
Trap的使用
// 定义一个leave 变量,类型为TInt TrapD的使用 // 调用函数,同时定义leave code变量 |
从上面可以看出,Trap和TrapD是基本相同的原理,只是TrapD更加简单使用。
2.2 使用User::LeaveXXX()
Leaves 可能由系统的内部错误触发,也可能由程序员显式地触发。有以下几种方式显式地(explicitly)触发。
·User::LeaveIfError():带着一个error code调用,如果error code不是KerrNone,那表明函数发生了leave。
·User::LeaveNoMemory()
·User::LeaveIfNull():一个指针变量作为参数,如果指针为NULL,那么函数leave
·User::Leave() 不检查任何事项。仅仅leave。
3、总结
Trap/Leave和传统的C++的异常处理不同之处在于,symbian仅仅返回一个TInt类型的错误代码(error code),而C++的异常处理可以抛出(throw)任何对象。也就是说,symbian的两种异常处理方式仅仅对抛出的error code的类型作处理。
一个函数的Leave可以由两种情况产生,一种由系统触发,另外一种由程序员触发(利用User::Leave()和其派生函数)。当leave发生时。系统会遍历所有调用的函数,直到发现Trap和TrapD为止。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10294527/viewspace-126410/ ,如需转载,请注明出处,否则将追究法律责任。