全部博文(668)
分类:
2008-08-07 09:06:23
这篇文章系统地来看看 SEH 在 C++ 程序中的各种使用情况。
先来一个简单的例子
其实简单的例子,就是把以前的使用 SEH 机制的 C 程序,改称 C++ 程序,看它能正常编译和运行否?什么意思,很简单,就是把原来的 .c 程序的扩展名改为 .cpp 文件,也即此时 VC 编译器会采用 C++ 语言来编译此程序(这也即为 C++ 程序了)。朋友们试试吧!代码如下:
// 注意,这是 C++ 程序,文件名为: SEH-test.cpp
#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");
}
是不是能编译通过,而且运行结果也和以前 c 程序的运行结果完全一致,如下:
hello
in try
in try
in filter 1
in filter 2
in finally
in except 2
world
Press any key to continue
来一个真正意义上的 C++ 程序,且使用 SEH 机制
也许很多程序员朋友对上面的例子不以为然,觉得它说明不了什么问题。好的,现在我们来看一个 真正意义上的 C++ 程序,且使用 SEH 机制。什么是真正意义上的 C++ 程序,当然是采用了。看例子吧!代码如下(其实就是在上面程序的基础上加了一个 class ):
// 注意,这是 C++ 程序,文件名为: SEH-test.cpp
#include "stdio.h"
class A
{
public:
void f1() {}
void f2() {}
};
void test1()
{
A a1;
A a2,a3;
a2.f1();
a3.f2();
}
void test()
{
int* p = 0x00000000; // pointer to NULL
__try
{
// 这里调用 test1 函数,它函数内部会创造 object
// 应该属于 100% 的 C++ 程序了吧!
test1();
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");
}
总结
通过以上实践得知, SEH 的确可以在 C++ 程序中使用,而且 SEH 不仅可以在 C++ 程序中使用;更进一步, SEH 异常机制( try-except 和 try-finally )还可以与 C++ 异常处理模型( try-catch ),两者在同一个 C++ 程序中混合使用,这在下一篇文章中接着讨论。
但问题是, MSDN 的忠告( C 程序中使用 try-except 和 try-finally ;而 C++ 程序则应该使用 try-catch ),这岂不是完全属于吓唬人吗?非也!非也!微软的建议一点也没有错, SEH 与 C++ 异常处理机制混合使用时,的确有一定的约束(虽然,平时我们很少关心这一点),这同样也在下一篇文章中详细接着讨论, 程序员朋友们,继续吧!