鱼和熊掌兼得——在VC++中混用C++异常和结构化异常

转载 2011年01月24日 23:31:00

很长时间没有更新自己的博客了,今天算是有一点闲暇时间吧,写点东西,献给那些经常关注我博客的网友。今天的话题还是关于异常处理的。

       在我学习C++ 以及VC++ 甚至windows编程的很长一段时间里,对于异常是没什么概念的,也不经常使用,甚至当我看到java的程序员几乎把所有的代码都用异常包裹起来的时候,我都觉得他们有点变态。

       在一个偶然的机会,我也不知道为什么我居然成了一名网游服务端的主程(其实我梦想的是写超炫的客户端),写服务程序,那要求就是高稳定,高性能,高度灵活,高扩展性,对于性能我是不怎么担心的,甚至扩展性我也不担心,灵活性就用lua搞定吧,可是稳定性对我却是一个不小的挑战。人非圣贤,孰能无过?因此代码中总是隐藏着很多莫名其妙的问题,这可是服务程序啊,任何的问题都可能导致严重的后果。你可以想象一下几万人甚至几十万人因为你糟糕的服务程序,而同时砸鼠标和键盘的样子,我只能默默祈祷他们不要认识我,否则我都不敢上街了,说到这其实可以看出当个程序员有多麽的不容易!

       在这些问题面前我能做的就是把异常处理这招用上了,开始我使用了的C++的异常处理,可是我沮丧的发现有些异常居然没法截获,程序依然固执的退出了事,郁闷,超级郁闷,于是我琢磨着放弃这个该死的C++异常处理,换用Windows系统的结构化异常处理,可是更糟糕的事情发生了,结构化异常的语法太怪异了,居然没有throw,而要使用一个函数RaiseException,同时C++的异常有无法截获了,哎,真是鱼和熊掌啊!怎么办?本着试试的态度,我在代码中既写了C++的异常处理,也用了一些结构化异常处理的代码,结果编译时,编译器告诉我不能在C++中使用结构化异常,要混用就要打开/EHsc开关,我在项目属性的C/C++选项下的代码生成选项中找到了它,选项名称是启用C++异常,下拉框中有个/EHsc的选项,于是我使用了它,开始编译,哦,非常棒!代码都编过了。我感觉非常的棒,可是等等,好像问题还是没有解决,两种异常处理在代码中还是水火不容的,怎么办?这下不知道怎么办了。

通常VC++的程序员在不知道怎么办的时候,最好的方法就是(注意不是上网)——而是打开MSDN,我在里面找到/EH选项的帮助,都是些没什么用的信息,老习惯我点了几个里面的连接,其中有一个名字叫做_set_se_translator的函数让我眼睛一亮,凭着多年看MSDN的经验,我相信这后面已经隐藏着一个惊天的秘密,微软的帮助就是这样,在一堆没用的说明的后面隐藏着很多非常非常有用的信息,就像当年那个少林武僧把九阳真经隐藏在金刚经中一样。

点击过去后,第一句话就让我非常激动,它是这样说的:

Handles Win32 exceptions (C structured exceptions) as C++ typed exceptions.

直接翻译的话就是处理Win32异常(C风格结构化异常)像C++类型的异常,说白了就是使用C++异常风格处理C风格的异常,这正是我真正的目的,真正意义上的混用两种异常处理,使用C++风格的简单优雅,使用结构化异常的强大和高效。我在猜想微软是不是也有程序员像我一样遇到这样的问题,于是他们就发明了这个非常棒的方法?

这个函数的使用很简单就是设置一个处理结构化异常的函数指针,同时自己去实现这个函数。

_set_se_translator函数的原型如下:

_se_translator_function _set_se_translator(

   _se_translator_function seTransFunction

);

结构化异常处理函数的原型如下:

typedef void (*_se_translator_function)(unsigned int, struct _EXCEPTION_POINTERS* );

下面我就直接将MSDN中的例子代码放在这里,供大家参考,以防有些网友使用MSDN不熟悉看半天也找不到这个函数。

// crt_settrans.cpp

// compile with: /EHa

#include <stdio.h>

#include <windows.h>

#include <eh.h>

 

void SEFunc();

void trans_func( unsigned int, EXCEPTION_POINTERS* );

 

class SE_Exception

{

private:

    unsigned int nSE;

public:

    SE_Exception() {}

    SE_Exception( unsigned int n ) : nSE( n ) {}

    ~SE_Exception() {}

    unsigned int getSeNumber() { return nSE; }

};

int main( void )

{

    try

    {

        _set_se_translator( trans_func );

        SEFunc();

    }

    catch( SE_Exception e )

    {

        printf( "Caught a __try exception with SE_Exception./n" );

    }

}

void SEFunc()

{

    __try

    {

        int x, y=0;

        x = 5 / y;

    }

    __finally

    {

        printf( "In finally/n" );

    }

}

void trans_func( unsigned int u, EXCEPTION_POINTERS* pExp )

{

    printf( "In trans_func./n" );

    throw SE_Exception();

}

 

最后在我自己的项目中,我也使用了类似的设计风格,我定义了一个比这个例子中异常类更强大的异常类,最终做到了C++异常和结构化异常的完美结合。当然我的服务程序因此而变得异常健壮,所有的异常都被截获了,程序非常的稳定,至此服务程序的稳定性问题算是有一个好的解决方案了。当然我不能完全依赖于完善的异常处理机制,还是要将程序中固有的的错误解决的越多越好,这也是截获了异常后,要进一步做的工作。

希望此文真正的帮到了那些像我一样奋战在服务端程序开发一线的网友们!

在VC++中混用C++异常和结构化异常

 在初学VC的时候,总以为try()catch(...)可以抓到所有的异常. 在开发之前开发的一个服务器程序中,才发现服务器经常莫名其妙的宕机了.一直觉得很诡异.   直到后来看了很多资料才明白结构化...

vc++6中的结构化异常处理try-except-finally语句

原帖及讨论:http://bbs.bc-cn.net/dispbbs.asp?boardID=55&ID=166791 */ ----------------------------------...
  • e_wsq
  • e_wsq
  • 2013年11月28日 16:27
  • 525

Win32结构化异常处理(SEH)——终止处理程序(__try/__finally)

环境:VC++6.0, Windows XP SP3        当我们想编写一个健壮的程序时,我们会用到异常处理,对各种异常进行考虑并进行处理。现在在各种语言都有自己的异常处理机制,比如C++的t...

SEH——Structured Exception Handling(结构化异常处理)

SEH是windows操作系统处理程序错误或异常的技术。SEH是一种系统体制,与具体的程序设计语言无关,但是windows下的编译器多使用SEH实现异常处理。     系统级别的SEH比较好理解,利...

Win32结构化异常处理(SEH)——终止处理程序(__try/__finally)

环境:VC++6.0, Windows XP SP3         当我们想编写一个健壮的程序时,我们会用到异常处理,对各种异常进行考虑并进行处理。现在在各种语言都有自己的异常处理机制,比如C...
  • pofante
  • pofante
  • 2011年12月05日 22:09
  • 2068

Visual C++异常处理机制原理与应用(五)——C/C++结构化异常处理之try-except异常处理的使用(下)

在前面几篇文章中,我们介绍了VC++结构化异常处理的相关内容,目前其用途仅限于捕获代码中本来就存在的异常,比如访问违规、除数为0等异常情况。其实在很多场合,我们也完全可以利用这种机制,触发一个异常,然...
  • LPWSTR
  • LPWSTR
  • 2017年12月04日 16:37
  • 10
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:鱼和熊掌兼得——在VC++中混用C++异常和结构化异常
举报原因:
原因补充:

(最多只允许输入30个字)