SEH的綜合(轉(zhuǎn))
SEH模型主要包括try-except異常處理機(jī)制和try-finally結(jié)束處理機(jī)制,而且這兩者能夠很好地有機(jī)統(tǒng)一起來(lái),它們結(jié)合使用時(shí),能夠提供給程序員非常強(qiáng)大、非常靈活的控制手段。其實(shí)這在上一篇文章中的幾個(gè)例子中已經(jīng)使用到,這里將繼續(xù)進(jìn)行系統(tǒng)的介紹,特別是try-except和 try-finally結(jié)合使用時(shí)的一些細(xì)節(jié)問(wèn)題。
try-except和try-finally組合使用
try-except和try-finally可以組合起來(lái)使用,它們可以是平行線性的關(guān)系,也可以是嵌套的關(guān)系。而且不僅是try-except語(yǔ)句中可以嵌套try-finally語(yǔ)句;同時(shí)try-finally語(yǔ)句中也可以嵌套try-except語(yǔ)句。所以它們的使用起來(lái)非常靈活,請(qǐng)看下面的代碼:
// 例程1,try-except語(yǔ)句與try-finally語(yǔ)句平行關(guān)系
#include <stdio.h>
void main()
{
puts("hello");
__try
{
int* p;
puts("__try塊中");
// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}
__try
{
}
__finally
{
puts("__finally塊中");
}
puts("world");
}
// 例程2,try-except語(yǔ)句中嵌套try-finally
#include <stdio.h>
void main()
{
puts("hello");
__try
{
__try
{
int* p;
puts("__try塊中");
// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__finally
{
// 這里會(huì)被執(zhí)行嗎
puts("__finally塊中");
}
}
__except(1)
{
puts("__except塊中");
}
puts("world");
}
// 例程3,try-finally語(yǔ)句中嵌套try-except
#include <stdio.h>
void main()
{
puts("hello");
__try
{
__try
{
int* p;
puts("__try塊中");
// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}
}
__finally
{
puts("__finally塊中");
}
puts("world");
}
try-except和try-finally組合使用時(shí),需注意的事情
在C++異常模型中,一個(gè)try block塊可以擁有多個(gè)catch block塊相對(duì)應(yīng),但是在SEH模型中,一個(gè)__try塊只能是擁有一個(gè)__except塊或一個(gè)__finally塊相對(duì)應(yīng),例如下面的程序代碼片斷是存在語(yǔ)法錯(cuò)誤的。
// 例程1,一個(gè)__try塊,兩個(gè)__except塊
#include <stdio.h>
void main()
{
puts("hello");
__try
{
int* p;
puts("__try塊中");
// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}
// 這里有語(yǔ)法錯(cuò)誤
__except(1)
{
puts("__except塊中");
}
puts("world");
}
// 例程2,一個(gè)__try塊,兩個(gè)__finally塊
#include <stdio.h>
void main()
{
puts("hello");
__try
{
puts("__try塊中");
}
__finally
{
puts("__finally塊中");
}
// 這里有語(yǔ)法錯(cuò)誤
__finally
{
puts("__finally塊中");
}
puts("world");
}
// 例程3,一個(gè)__try塊,對(duì)應(yīng)一個(gè)__finally塊和一個(gè)__except塊
#include <stdio.h>
void main()
{
puts("hello");
__try
{
int* p;
puts("__try塊中");
// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__finally
{
puts("__finally塊中");
}
// 這里有語(yǔ)法錯(cuò)誤
__except(1)
{
puts("__except塊中");
}
puts("world");
}
溫過(guò)而知新
這里給出最后一個(gè)簡(jiǎn)單的try-except和try-finally相結(jié)合的例子,讓我們溫過(guò)而知新。代碼如下(這是MSDN中的例程):
#include "stdio.h"
void test()
{
int* p = 0x00000000; // pointer to NULL
__try
{
puts("in try");
__try
{
puts("in try");
// causes an access violation exception;
// 導(dǎo)致一個(gè)存儲(chǔ)異常
*p = 13;
// 呵呵,注意這條語(yǔ)句
puts("這里不會(huì)被執(zhí)行到");
}
__finally
{
puts("in finally");
}
// 呵呵,注意這條語(yǔ)句
puts("這里也不會(huì)被執(zhí)行到");
}
__except(puts("in filter 1"), 0)
{
puts("in except 1");
}
}
void main()
{
puts("hello");
__try
{
test();
}
__except(puts("in filter 2"), 1)
{
puts("in except 2");
}
puts("world");
}
上面的程序運(yùn)行結(jié)果如下:
hello
in try
in try
in filter 1
in filter 2
in finally
in except 2
world
Press any key to continue
下面用圖表描述一下上面例程運(yùn)行時(shí)的執(zhí)行流程,如下圖所示。
總結(jié)
(1) try-except和try-finally可以組合起來(lái)使用,它們可以是平行線性的關(guān)系,也可以是嵌套的關(guān)系。而且不僅是try-except語(yǔ)句中可以嵌套try-finally語(yǔ)句;同時(shí)try-finally語(yǔ)句中也可以嵌套try-except語(yǔ)句。
(2) 一個(gè)__try塊只能是擁有一個(gè)__except塊或一個(gè)__finally塊相對(duì)應(yīng)。
至此,關(guān)于SEH的__try、__except、__finally、__leave模型已經(jīng)基本闡述完畢,但是主人公阿愚認(rèn)為,有關(guān)SEH模型機(jī)制,還有一個(gè)非常關(guān)鍵的內(nèi)容沒(méi)有闡述到,那就是SEH與C++異常處理模型可以結(jié)合使用嗎?如果可以的話?它們組合使用時(shí),有什么限制嗎?或帶來(lái)什么不良后果嗎?
大家知道,Windows平臺(tái)提供的SEH機(jī)制雖然主要是應(yīng)用于C語(yǔ)言的程序,以便第三廠商開(kāi)發(fā)出高效的設(shè)備驅(qū)動(dòng)程序來(lái)。但是__try、__except、__finally、__leave模型同樣也可以在C++程序中使用,這在MSDN中已經(jīng)提到,雖然微軟還是建議,在 C++程序中盡量采用C++的異常處理模型。
但是對(duì)于廣大程序員而言,大家有必要知道,__try、__except、__finally、__leave模型在C++程序中使用時(shí)的一些限制。下一篇文章中,阿愚將把自己總結(jié)的一些經(jīng)驗(yàn)和體會(huì)與大家一塊分享。去看看吧!GO!
posted on 2008-01-25 19:28 大龍 閱讀(949) 評(píng)論(0) 編輯 收藏 引用