导读:
从本篇文章开始,将全面阐述__try,__except,__finally,__leave异常模型机制,它也即是Windows系列操作系统平台上提供的SEH模型。主人公阿愚将在这里与大家分享SEH( 结构化异常处理)的学习过程和经验总结。 深入理解请参阅<<windows 核心编程>>第23, 24章.
SEH实际包含两个主要功能:结束处理(termination handling)和异常处理(exception handling)
每当你建立一个try块,它必须跟随一个finally块或一个except块。
一个try 块之后不能既有finally块又有except块。但可以在try - except块中嵌套try - finally块,反过来
也可以。
__try __finally关键字用来标出结束处理程序两段代码的轮廓
不管保护体(try块)
是如何退出的。不论你在保护体中使用return,还是goto,或者是longjump,结束处理程序
(finally块)都将被调用。
在try使用__leave关键字会引起跳转到try块的结尾
SEH有两项非常强大的功能。当然,首先是异常处理模型了,因此,这篇文章首先深入阐述SEH提供的异常处理模型。另外,SEH还有一个特别强大的功能,这将在下一篇文章中进行详细介绍。
try-except入门
SEH的异常处理模型主要由try-except语句来完成,它与标准C++所定义的异常处理模型非常类似,也都是可以定义出受监控的代码模块,以及定义异常处理模块等。还是老办法,看一个例子先,代码如下:
//seh-test.c
{
// 定义受监控的代码模块
__try
{
puts( " in try " );
}
// 定义异常处理模块
__except( 1 )
{
puts( " in except " );
}
}
呵呵!是不是很简单,而且与C++异常处理模型很相似。当然,为了与C++异常处理模型相区别,VC编译器对关键字做了少许变动。首先是在每个关键字加上两个下划线作为前缀,这样既保持了语义上的一致性,另外也尽最大可能来避免了关键字的有可能造成名字冲突而引起的麻烦等;其次,C++异常处理模型是使用catch关键字来定义异常处理模块,而SEH是采用__except关键字来定义。并且,catch关键字后面往往好像接受一个函数参数一样,可以是各种类型的异常数据对象;但是__except关键字则不同,它后面跟的却是一个表达式(可以是各种类型的表达式,后面会进一步分析)。
try-except进阶
与C++异常处理模型很相似,在一个函数中,可以有多个try-except语句。它们可以是一个平面的线性结构,也可以是分层的嵌套结构。例程代码如下:
// 例程1
// 平面的线性结构
{
__try
{
puts( " in try " );
}
__except( 1 )
{
puts( " in except " );
}
// 又一个try-except语句
__try
{
puts( " in try1 " );
}
__except( 1 )
{
puts( " in except1 " );
}
}
// 例程2
// 分层的嵌套结构