下面的代码举例说明了一种方法,指出所发生异常的类别:
BOOL Func_SEHExceptionGetCodeBase()
{
 int x,y;
 __try{
  x = 0;
  y = 4/x;
 }
 __except((GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO) ? /
                                EXCEPTION_EXECUTE_HANDLER :/
                EXCEPTION_CONTINUE_SEARCH)
 {
  file://handle divide by zero exception
 }
}
GetExceptionCode返回一个值,该值指出所发生异常的种类:
下面列出所有预定义的异常和相应的含意,这些内容取自Platform SDK文档。这些异常标识符可以在WinBase.h文件中找到。我们对这些异常做了分类。
1. 与内存有关的异常
• E X C E P T I O N _ A C C E S S _ V I O L AT I O N。线程试图对一个虚地址进行读或写,但没有做适当的存取。这是最常见的异常。
• E X C E P T I O N _ D ATAT Y P E _ M I S A L I G N M E N T。线程试图读或写不支持对齐( a l i g n m e n t)的硬件上的未对齐的数据。例如, 1 6位数值必须对齐在2字节边界上,3 2位数值要对齐在4字节边界上。
• E X C E P T I O N _ A R R AY _ B O U N D S _ E X C E E D E D。线程试图存取一个越界的数组元素,相应的硬件支持边界检查。
• E X C E P T I O N _ I N _ PA G E _ E R R O R。由于文件系统或一个设备启动程序返回一个读错误,造成不能满足要求的页故障。
• E X C E P T I O N _ G U A R D _ PA G E。一个线程试图存取一个带有PA G E _ G U A R D保护属性的内存页。该页是可存取的,并引起一个E X C E P T I O N _ G U A R D _ PA G E异常。
• EXCEPTION_STA C K _ O V E R F L O W。线程用完了分配给它的所有栈空间。
• E X C E P T I O N _ I L L E G A L _ I N S T R U C T I O N。线程执行了一个无效的指令。这个异常由特定的C P U结构来定义;在不同的C P U上,执行一个无效指令可引起一个陷井错误。
• E X C E P T I O N _ P R I V _ I N S T R U C T I O N。线程执行一个指令,其操作在当前机器模式中不允许。
2. 与异常相关的异常
• E X C E P T I O N _ I N VA L I D _ D I S P O S I T I O N。一个异常过滤器返回一值,这个值不是E X C E P T I O N _ E X E C U T E _ H A N D L E R 、E X C E P T I O N _ C O N T I N U E _ S E A R C H、E X C E P T I O N _ C O N T I N U E _ E X E C U T I O N三者之一。
• E X C E P T I O N _ N O N C O N T I N U A B L E _ E X C E P T I O N。一个异常过滤器对一个不能继续的异常返回E X C E P T I O N _ C O N T I N U E _ E X E C U T I O N。
3. 与调试有关的异常
• EXCEPTION_BREAKPOINT。遇到一个断点。
• E X C E P T I O N _ S I N G L E _ S T E P。一个跟踪陷井或其他单步指令机制告知一个指令已执行完毕。
• E X C E P T I O N _ I N VA L I D _ H A N D L E。向一个函数传递了一个无效句柄。
4. 与整数有关的异常
• EXCEPTION_INT_DIVIDE_BY_ZERO。线程试图用整数0来除一个整数
• EXCEPTION_INT_OVERFLOW。一个整数操作的结果超过了整数值规定的范围。
5. 与浮点数有关的异常
• E X C E P T I O N _ F LT _ D E N O R M A L _ O P E R A N D。浮点操作中的一个操作数不正常。不正常的值是一个太小的值,不能表示标准的浮点值。
• EXCEPTION_FLT _ D I V I D E _ B Y _ Z E R O。线程试图用浮点数0来除一个浮点。
• EXCEPTION_FLT _ I N E X A C T _ R E S U LT。浮点操作的结果不能精确表示成十进制小数。
• EXCEPTION_FLT _ I N VA L I D _ O P E R AT I O N。表示任何没有在此列出的其他浮点数异常。
• EXCEPTION_FLT _ O V E R F L O W。浮点操作的结果超过了允许的值。
• EXCEPTION_FLT _ S TA C K _ C H E C K。由于浮点操作造成栈溢出或下溢。
• EXCEPTION_FLT _ U N D E R F L O W。浮点操作的结果小于允许的值。
函数GetExceptionCode只能在一个过滤器中调用(__except之后的括号里),或在一个异常处理程序中被调用。记住,不能在一个异常过滤器函数里面调用GetExceptionCode。编译程序会捕捉这样的错误。

还有,上面的异常代码遵循在WinError.h文件中定义的有关错误代码的规则。(捎后我会写一段小的文章表明WinError.h的作用)

GetExceptionInformation
当一个异常发生时,操作系统要向引起异常的线程的栈里压入三个结构,这三个结构是:EXCEPTION_RECORD结构、CONTEXT结构和EXCEPTION_POINTERS结构。
EXCEPTION_RECORD结构包含有关已发生异常的独立于C P U的信息,
CONTEXT结构包含已发生异常的依赖于C P U的信息。
EXCEPTION_POINTERS结构只有两个数据成员,二者都是指针,分别指向被压入栈的EXCEPTION_POINTERS和CONTEXT结构。

为了取得这些信息并在你自己的程序中使用这些信息,需要调用GetExceptionInformation
函数:这个内部函数返回一个指向EXCEPTION_POINTERS结构的指针。

关于GetExceptionInformation函数,要记住的最重要事情是它只能在异常过滤器中调用,因为仅仅在处理异常过滤器时, EXCEPTION_RECORD和EXCEPTION_POINTERS才是有效的。一旦控制被转移到异常处理程序,栈中的数据就被删除。

如果需要在你的异常处理程序块里面存取这些异常信息(虽然很少有必要这样做),必须将EXCEPTION_POINTERS结构所指向的CONTEXT数据结构和/或EXCEPTION_RECORD数据结构保存在你所建立的一个或多个变量里。下面的代码说明了如何保存EXCEPTION_RECORD和CONTEXT数据结构:
void Func_SEHExceptionGetInfo()
{
 EXCEPTION_RECORD SaveExceptRec;
 CONTEXT SaveExceptContext;
 int x = 0;

__try{
  x = 5/x;
 }
 __except(SaveExceptRec =
        *(GetExceptionInformation())->ExceptionRecord,
     SaveExceptContext =
     *(GetExceptionInformation())->ContextRecord,
     EXCEPTION_EXECUTE_HANDLER
     )
 {
  switch(SaveExceptRec.ExceptionCode)
  {
   file://Here, Do your thing for code value
   
  }

}
}
上面的代码中:注意在异常过滤器中C语言逗号(,)操作符的使用。许多程序员不习惯使用这个操作符。它告诉编译程序从左到右执行以逗号分隔的各表达式。当所有的表达式被求值之后,返回最后的(或最右的)表达式的结果。

下面是EXCEPTION_RECORD的结构:
typedef struct _EXCEPTION_RECORD {
DWORD ExceptionCode;
DWORD ExceptionFlags;
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID ExceptionAddress;
DWORD NumberParameters;
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;
EXCEPTION_RECORD结构包含有关最近发生的异常的详细信息,这些信息独立于C P U:
• ExceptionCode包含异常的代码。这同内部函数GetExceptionCode返回的信息是一样的。

[转]C++异常处理 12相关推荐

  1. Java异常处理12条军规

    摘要: 简单实用的建议. 原文:Java异常处理12条军规 公众号:Spring源码解析 Fundebug经授权转载,版权归原作者所有. 在Java语言中,异常从使用方式上可以分为两大类: Check ...

  2. C++语言程序设计——异常处理12

    一,异常处理的基本思路 二,C++异常处理的实现 三,异常处理中的构造和析构 四,标准程序库异常处理 五,深度探索

  3. 面试准备工作 -戈多编程

    一.C#基础知识 1.变量与常量(值类型和引用类型) 2.表达式与运算符 (1)算术运算符(2)赋值运算符(3)关系运算符(4)逻辑运算符(5)移位运算符(6)其他特殊运算符 3.字符与字符串 (1) ...

  4. C++语言程序设计视频教程_清华大学_郑莉(基础篇+进阶篇)

    C++语言程序设计视频教程_清华大学_郑莉(基础篇) 第一章:绪论 1.1 导学 1.2 计算机系统简介 1.3计算机语言和程序设计方法的发展 1.4 面向对象的基本概念 1.5 程序的开发过程 1. ...

  5. [改善Java代码]不使用stop方法停止线程

    线程启动完毕后,在运行可能需要终止,Java提供的终止方法只有一个stop,但是不建议使用此方法,因为它有以下三个问题: (1)stop方法是过时的 从Java编码规则来说,已经过时的方式不建议采用. ...

  6. scala学习 之 及 基本和高级用法(二)

    目录 1. Scala的数据类型 2. Scala变量 3. Scala 访问修饰符 4. Scala 方法和函数 5. Scala数组 6. Collection(集合) 7. Scala的类和对象 ...

  7. c#语言程序设计上机实验,C#语言程序设计基础实验指导(第3版)

    第1章 绪论 1.1 知识点回顾 1.2 实验目的和要求 1.3 实验内容 1.4 实验指导 实验1-1 模拟电子邮箱注册 实验1-2 创建和调用C#类库程序 1.5 补充上机练习 第2章 C#数据类 ...

  8. Java SSM篇5——SpringMVC

    Java SSM篇5--SpringMVC 1.MVC模式 MVC是软件工程中的一种软件架构模式,它是一种分离业务逻辑与显示界面的开发思想 M(model)模型:处理业务逻辑,封装实体 V(view) ...

  9. python核心编程--笔记(不定时跟新)(转)

    的解释器options: 1.1 –d   提供调试输出 1.2 –O   生成优化的字节码(生成.pyo文件) 1.3 –S   不导入site模块以在启动时查找python路径 1.4 –v   ...

最新文章

  1. VueJs开发笔记—IDE选择和优化、框架特性、数据调用、路由选项及使用
  2. MVC开发Markdown编辑器(1)
  3. 更好地认知Azure
  4. javafx FlowPane布局
  5. initWithFrame方法的理解(转)
  6. 使用git-bash向码云提交项目
  7. cocos2dx进阶学习之场景切换
  8. 以太坊新生合约总数骤减;比特币大跌,本周主链排名震荡 | 数据周榜
  9. Android7.0以后的ninja编译系统
  10. python实现微信自动发信息软件_Python实现给微信好友自动发送消息的示例
  11. 小程序图片上传无反应
  12. java数组的四种拷贝方式
  13. 货币转换python代码_在Python中创建货币转换器
  14. 问题解决:VScode在使用中文输入法时出现vim insert模式变成vim normal的奇怪现象( jj 映射成esc)
  15. 江苏省发布大数据引领推动融合发展专项行动计划
  16. linux修改主机名命令
  17. 什么是SpringMVC?SpringMVC之hello.jsp实现过程 问题:SpringMVC在JSP页面取不到ModelAndView中的值(已解决)
  18. 服务器的原点和限位信号,CANopen--基于DS402协议的伺服电机原点回零模式实现
  19. ThinkPHP模版引擎之变量输出详解
  20. JAVA简单连接数据库(Mysql)

热门文章

  1. python scikit learn 关闭开源_Python机器学习工具:Scikit-Learn介绍与实践
  2. 软件模拟PWM——呼吸灯小程序的理解
  3. mysql nest loop伪代码_Nested Loop Join
  4. mysql 日期 1970_Mysql中处理1970年前的日期(unixtime为负数的情况)负数时间戳格式化...
  5. houdini 做选点效果
  6. DE15 Introduction to Fourier Series
  7. cleanlab(解决图像标记错误)
  8. mysql 协议测试_mysqlslap压力测试mysql
  9. 2020最新文本检测算法TextFuseNet
  10. java实现浏览器_利用Java实现网页浏览器