当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

玩转setjmp与longjmp

    不要忘记,前面我们得出过结论,C语言中提供的这种异常处理机制,与C++中的异常处理模型很相似。例如,可以定义出类似的try block(受到监控的代码);catch block(异常错误的处理模块);以及可以随时抛出的异常(throw语句)。所以说,我们可以通过一种非常有技巧的封装,来达到对setjmp和longjmp的使用方法(或者说语法规则),基本与C++中的语法一致。很有诱惑吧!
    首先展示阿愚封装的在C语言环境中异常处理框架

      1、首先是接口的头文件,主要采用“宏”技术!代码如下:

    /*************************************************
    * author: 王胜祥 *
    * email: <[email protected]> *
    * date: 2005-03-07 *
    * version: *
    * filename: ceh.h *
    *************************************************/


    /********************************************************************

    This file is part of CEH(Exception Handling in C Language).

    CEH is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CEH is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

      注意:这个异常处理框架不支持线程安全,不能在多线程的程序环境下使用。
    如果您想在多线程的程序中使用它,您可以自己试着来继续完善这个
    框架模型。
    *********************************************************************/

    #include <stdio.h>
    #include <signal.h>
    #include <setjmp.h>
    #include <stdlib.h>
    #include <float.h>
    #include <math.h>
    #include <string.h>


    ////////////////////////////////////////////////////
    /* 与异常有关的结构体定义 */
    typedef struct _CEH_EXCEPTION {
    int err_type; /* 异常类型 */
    int err_code; /* 错误代码 */
    char err_msg[80]; /* 错误信息 */
    }CEH_EXCEPTION; /* 异常对象 */

    typedef struct _CEH_ELEMENT {
    jmp_buf exec_status;
    CEH_EXCEPTION ex_info;

    struct _CEH_ELEMENT* next;
    } CEH_ELEMENT; /* 存储异常对象的链表元素 */
    ////////////////////////////////////////////////////


    ////////////////////////////////////////////////////
    /* 内部接口定义,操纵维护链表数据结构 */
    extern void CEH_push(CEH_ELEMENT* ceh_element);
    extern CEH_ELEMENT* CEH_pop();
    extern CEH_ELEMENT* CEH_top();
    extern int CEH_isEmpty();
    ////////////////////////////////////////////////////


    /* 以下是外部接口的定义 */
    ////////////////////////////////////////////////////
    /* 抛出异常 */
    extern void thrower(CEH_EXCEPTION* e);

    /* 抛出异常 (throw)
    a表示err_type
    b表示err_code
    c表示err_msg
    */
    #define throw(a, b, c) \
    { \
    CEH_EXCEPTION ex; \
    memset(&ex, 0, sizeof(ex)); \
    ex.err_type = a; \
    ex.err_code = b; \
    strncpy(ex.err_msg, c, sizeof(c)); \
    thrower(&ex); \
    }

    /* 重新抛出原来的异常 (rethrow)*/
    #define rethrow thrower(ceh_ex_info)
    ////////////////////////////////////////////////////


    ////////////////////////////////////////////////////
    /* 定义try block(受到监控的代码)*/
    #define try \
    { \
    int ___ceh_b_catch_found, ___ceh_b_occur_exception; \
    CEH_ELEMENT ___ceh_element; \
    CEH_EXCEPTION* ceh_ex_info; \
    memset(&___ceh_element, 0, sizeof(___ceh_element)); \
    CEH_push(&___ceh_element); \
    ceh_ex_info = &___ceh_element.ex_info; \
    ___ceh_b_catch_found = 0; \
    if (!(___ceh_b_occur_exception=setjmp(___ceh_element.exec_status))) \
    {


    /* 定义catch block(异常错误的处理模块)
    catch表示捕获所有类型的异常
    */
    #define catch \
    } \
    else \
    { \
    CEH_pop(); \
    ___ceh_b_catch_found = 1;


    /* end_try表示前面定义的try block和catch block结束 */
    #define end_try \
    } \
    { \
    /* 没有执行到任何的catch块中 */ \
    if(!___ceh_b_catch_found) \
    { \
    CEH_pop(); \
    /* 出现了异常,但没有捕获到任何异常 */ \
    if(___ceh_b_occur_exception) thrower(ceh_ex_info); \
    } \
    } \
    }


    /* 定义catch block(异常错误的处理模块)
    catch_part表示捕获一定范围内的异常
    */
    #define catch_part(i, j) \
    } \
    else if(ceh_ex_info->err_type>=i && ceh_ex_info->err_type<=j) \
    { \
    CEH_pop(); \
    ___ceh_b_catch_found = 1;


    /* 定义catch block(异常错误的处理模块)
    catch_one表示只捕获一种类型的异常
    */
    #define catch_one(i) \
    } \
    else if(ceh_ex_info->err_type==i) \
    { \
    CEH_pop(); \
    ___ceh_b_catch_found = 1;
    ////////////////////////////////////////////////////


    ////////////////////////////////////////////////////
    /* 其它可选的接口定义 */
    extern void CEH_init();
    ////////////////////////////////////////////////////


    2、另外还有一个简单的实现文件,主要实现功能封装。代码如下:

    /*************************************************
    * author: 王胜祥 *
    * email: <[email protected]> *
    * date: 2005-03-07 *
    * version: *
    * filename: ceh.c *
    *************************************************/


    /********************************************************************

    This file is part of CEH(Exception Handling in C Language).

    CEH is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CEH is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    注意:这个异常处理框架不支持线程安全,不能在多线程的程序环境下使用。
    如果您想在多线程的程序中使用它,您可以自己试着来继续完善这个
    框架模型。
    *********************************************************************/

    #include "ceh.h"

    ////////////////////////////////////////////////////
    static CEH_ELEMENT* head = 0;

    /* 把一个异常插入到链表头中 */
    void CEH_push(CEH_ELEMENT* ceh_element)
    {
    if(head) ceh_element->next = head;
    head = ceh_element;
    }


    /* 从链表头中,删除并返回一个异常 */
    CEH_ELEMENT* CEH_pop()
    {
    CEH_ELEMENT* ret = 0;

    ret = head;
    head = head->next;

    return ret;
    }


    /* 从链表头中,返回一个异常 */
    CEH_ELEMENT* CEH_top()
    {
    return head;
    }


    /* 链表中是否有任何异常 */
    int CEH_isEmpty()
    {
    return head==0;
    }
    ////////////////////////////////////////////////////


    ////////////////////////////////////////////////////
    /* 缺省的异常处理模块 */
    static void CEH_uncaught_exception_handler(CEH_EXCEPTION *ceh_ex_info)
    {
    printf("捕获到一个未处理的异常,错误原因是:%s! err_type:%d err_code:%d\n",
    ceh_ex_info->err_msg, ceh_ex_info->err_type, ceh_ex_info->err_code);
    fprintf(stderr, "程序终止!\n");
    fflush(stderr);
    exit(EXIT_FAILURE);
    }
    ////////////////////////////////////////////////////


 

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接