鱼和熊掌兼得——在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++中混用C++异常和结构化异常            很长时间没有更新自己的博客了,今天算是有一点闲暇时间吧,写点东西,献给那些经常关注我博客的网友。今天...
  • aasmfox
  • aasmfox
  • 2016年07月10日 07:09
  • 211

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

结构化异常处理看过一些,不过都忘了。某些类型的异常看来还需要结构化异常来处理,还是要根据场景来使用吧。等温习使用了之后,在详细介绍其中的妙处。------------------------ZT fr...
  • fantasyagain
  • fantasyagain
  • 2010年12月28日 22:07
  • 913

解《鱼和熊掌不可兼得》

鱼和熊掌不可兼得 以下言论是本人扮演角色的个人言论,与本人无关 想必各位肯定知道“鱼和熊掌不可兼得”这件事,当年上学的时候学了而已,看了看译文,如果说有人问你:鱼和熊掌为什么不可兼得?或者作者为什...
  • shaogaige
  • shaogaige
  • 2017年02月26日 11:22
  • 493

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

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

Windows 结构化异常与 C / C++异常的一些事

一直以来对“异常”以及相关的知识很模糊,这次做个整理,回答几个基本问题以帮助对“异常”的理解: C语言的异常C语言版的try/catch: setjmp, longjmp C++的异常(try/c...
  • vincentccnt
  • vincentccnt
  • 2015年01月20日 16:56
  • 1519

鱼和熊掌不可兼得

平时没遇到过,有一天,一哥们突然问这么个问题,才注意到这个细节:问题是:有两个接口(Interface)类,其中这连个interface中有同名不同返回值的抽象方法,现提供一个Class,要求其实现这...
  • zxr85
  • zxr85
  • 2009年12月20日 12:04
  • 697

Blockchain的鱼和熊掌系列(13)Integer Factorization

A public-key cryptosystem is based on the big integer factorization problem of number theory which w...
  • Canhui_WANG
  • Canhui_WANG
  • 2017年03月06日 14:11
  • 228

结构化异常处理和C++的异常处理区别

Windows异常由系统内核代码捕获,然后传递至用户层,多用于非法内存访问、指令错误等,其类型是CPU定义的,参见《X386保护模式编程》。 C++异常是C++编译器生成的结构(多在堆栈上),是普通的...
  • wxtsmart
  • wxtsmart
  • 2008年09月28日 17:54
  • 1824

Blockchain的鱼和熊掌系列(0) Intro

This is a test file.
  • Canhui_WANG
  • Canhui_WANG
  • 2016年12月05日 12:49
  • 339

鱼和熊掌不可兼得,钱和女人必须兼得?

        昨天晚上的日语课上有个同事说他和女朋友分手了,见过一次他女朋友的照片,很漂亮的一个女孩子,看起来也蛮贤惠的。听说明年就要结婚了的,突然分手还真的让我很惊讶,我和他不是很熟悉,不过听说分...
  • gaojian189
  • gaojian189
  • 2006年09月26日 22:52
  • 1251
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:鱼和熊掌兼得——在VC++中混用C++异常和结构化异常
举报原因:
原因补充:

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