SEH的綜合

轉載自http://blog.programfan.com/article.asp?id=9840

SEH模型主要包括try-except異常處理機制和try-finally結束處理機制,而且這兩者能夠很好地有機統一起來,它們結合使用時,能夠提供給程序員非常強大、非常靈活的控制手段。其實這在上一篇文章中的幾個例子中已經使用到,這裏將繼續進行系統的介紹,特別是try-except和try-finally結合使用時的一些細節問題。

try-except和try-finally組合使用


  try-except和try-finally可以組合起來使用,它們可以是平行線性的關係,也可以是嵌套的關係。而且不僅是try-except語句中可以嵌套try-finally語句;同時try-finally語句中也可以嵌套try-except語句。所以它們的使用起來非常靈活,請看下面的代碼:

// 例程1,try-except語句與try-finally語句平行關係
#include <stdio.h>
void main()
{
puts("hello");

__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}

__try
{
}
__finally
{
puts("__finally塊中");
}

puts("world");
}


// 例程2,try-except語句中嵌套try-finally
#include <stdio.h>

void main()
{
puts("hello");

__try
{
__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__finally
{
// 這裏會被執行嗎
puts("__finally塊中");
}
}
__except(1)
{
puts("__except塊中");
}

puts("world");
}


// 例程3,try-finally語句中嵌套try-except
#include <stdio.h>

void main()
{
puts("hello");

__try
{
__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}
}
__finally
{
puts("__finally塊中");
}

puts("world");
}

try-except和try-finally組合使用時,需注意的事情


  在C++異常模型中,一個try block塊可以擁有多個catch block塊相對應,但是在SEH模型中,一個__try塊只能是擁有一個__except塊或一個__finally塊相對應,例如下面的程序代碼片斷是存在語法錯誤的。

// 例程1,一個__try塊,兩個__except塊
#include <stdio.h>
void main()
{
puts("hello");

__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__except(1)
{
puts("__except塊中");
}
// 這裏有語法錯誤
__except(1)
{
puts("__except塊中");
}

puts("world");
}


// 例程2,一個__try塊,兩個__finally塊
#include <stdio.h>
void main()
{
puts("hello");

__try
{
puts("__try塊中");
}
__finally
{
puts("__finally塊中");
}
// 這裏有語法錯誤
__finally
{
puts("__finally塊中");
}

puts("world");
}


// 例程3,一個__try塊,對應一個__finally塊和一個__except塊
#include <stdio.h>
void main()
{
puts("hello");

__try
{
int* p;
puts("__try塊中");

// 下面拋出一個異常
p = 0;
*p = 25;
}
__finally
{
puts("__finally塊中");
}
// 這裏有語法錯誤
__except(1)
{
puts("__except塊中");
}

puts("world");
}

溫過而知新

  這裏給出最後一個簡單的try-except和try-finally相結合的例子,讓我們溫過而知新。代碼如下(這是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;
// 導致一個存儲異常
*p = 13;

// 呵呵,注意這條語句
puts("這裏不會被執行到");
}
__finally
{
puts("in finally");
}

// 呵呵,注意這條語句
puts("這裏也不會被執行到");
}
__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");
}

上面的程序運行結果如下:
hello
in try
in try
in filter 1
in filter 2
in finally
in except 2
world
Press any key to continue

下面用圖表描述一下上面例程運行時的執行流程,如下圖所示。



總結

  (1) try-except和try-finally可以組合起來使用,它們可以是平行線性的關係,也可以是嵌套的關係。而且不僅是try-except語句中可以嵌套try-finally語句;同時try-finally語句中也可以嵌套try-except語句。

   (2) 一個__try塊只能是擁有一個__except塊或一個__finally塊相對應。

  至此,關於SEH的__try、__except、__finally、__leave模型已經基本闡述完畢,但是主人公阿愚認爲,有關SEH模型機制,還有一個非常關鍵的內容沒有闡述到,那就是SEH與C++異常處理模型可以結合使用嗎?如果可以的話?它們組合使用時,有什麼限制嗎?或帶來什麼不良後果嗎?

  大家知道,Windows平臺提供的SEH機制雖然主要是應用於C語言的程序,以便第三廠商開發出高效的設備驅動程序來。但是__try、__except、__finally、__leave模型同樣也可以在C++程序中使用,這在MSDN中已經提到,雖然微軟還是建議,在C++程序中儘量採用C++的異常處理模型。

  但是對於廣大程序員而言,大家有必要知道,__try、__except、__finally、__leave模型在C++程序中使用時的一些限制。下一篇文章中,阿愚將把自己總結的一些經驗和體會與大家一塊分享。去看看吧!GO!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章