Windows核心编程 第25章 未处理异常和C ++异常(下)
这一节东西比较少,本应该归并在上一节里,但是昨天太晚了。就先把那些东西分为上了。这节里面就一个问题,C++异常与结构性异常的对比(try和__try的区别):
C++异常与结构性异常的对比
S E H是可用于任何编程语言的操作系统设施,而异常处理只能用于编写
C + +代码。如果你在编写C + +程序,你应该使用C + +异常处理而不是结构化异常处理。理由是C + +异常处理是语言的一部分,编译器知道 C + +类对象是什么。也就是说编译器能够自动生成代码来调用C + +对象析构函数,保证对象的清除。
但是也应该知道,Microsoft Visual C++编译器已经利用操作系统的结构化异常处理实现了C + +异常处理。所以当你建立一个 C++ try块时,编译器就生成一个 S E H_ _t r y块。一个C + +c a t c h测试变成一个S E H异常过滤器,并且c a t c h中的代码变成S E H_ _e x c e p t块中的代码。实际上,当你写一条C++ throw语句时,编译器就生成一个对Wi n d o w s的R a i s e E x c e p t i o n函数的调用。用于t h r o w语句的变量传递给R a i s e E x c e p t i o n作为附加的参数。
下面的代码段可以使上面的叙述更清楚一些。左边的函数使用 C + +异常处理,右边的函数说明了C + +编译器如何生成等价的结构化异常处理。
你可能注意到上面代码中一些有趣的细节。首先,函数 R a i s e E x c e p t i o n的调用使用了异常代码0 x E 0 6 D 7 3 6 3。这是由Visual C++的开发人员选择的软件异常代码,在引发C + +异常时使用。事实上你可以验证这一点,方法是打开调试程序的 E x c e p t i o n s对话框,滚动到异常列表的底部,见图2 5 - 1 5。
当引发了C + +异常时,总要使用E X C E P T I O N _ N O N C O N T I N U E A B L E标志。C + +异常不能被重新执行。对于诊断C + +异常的过滤器,如果返回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过滤器,就会发现它只能计算成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。
传递到R a i s e E x c e p t i o n的其余参数是用来作为一种机制,用于实际引发指定的变量。被引发的变量信息是如何传递到 R a i s e E x c e p t i o n的,这一点没有公开。但不难想像编译器的开发人员可以实现这一点。
最后要指出的是_ _ e x c e p t过滤器。这个过滤器的用途是将t h r o w变量的数据类型同用于C + +c a t c h语句的变量类型相比较。如果数据类型相同,过滤器返回 E X C E P T I O N _ E X E C U T E _H A N D L E R,导致c a t c h块(_ _ e x c e p t块)中的语句执行。如果数据类型不同,过滤器返回E X C E P T I O N _ C O N T N U E _ S E A R C H,导致c a t c h过滤器上溯要计算的调用树。
正常情况下,C + +异常处理不能使程序从硬件异常中恢复,硬件违规就是存取违规或零作除数这种异常。但微软已经对其编译器增加了这种支持能力。例如,下面的代码可以防止进程不正常地结束:(VS默认是Release可以,Debug的话还是会掉相关处理函数,然后弹异常窗)
同时catch里面还可以细分,就是判断异常类型然后做相应处理:Visuad C++有一种机制可以实现这一点。你需要做的是建立你自己的C + +类,在代码中用来标识结构性异常。这里是一个例子:
在每个线程的进入点函数里,调用静态成员函数 M a p S E t o C E。这个函数调用C运行时函数_ s e t _ s e _ t r a n s l a t o r,并传递 C S E类的 Tr a n s l a t e S E t o C E函数的地址作为参数。通过调用_ s e t _ s e _ t r a n s l a t o r,告诉C + +运行时系统,在结构性异常发生时调用 Tr a n s l a t e S E t o C E函数。这个函数构造一个C S E类对象并初始化两个数据成员以包含有关异常的 C P U独立和C P U依赖的信息。在构造了C S E对象之后,它就被引发,如同任何正常的变量可被引发一样。现在你的 C + +代码可以通过捕获一个这类的变量来处理结构性异常。
下面是如何捕获这个C + +对象的例子。
额...讲道理是应该先输出个111然后输出222的吧,结果是直接崩溃了。
Windows核心编程 第25章 未处理异常和C ++异常(下)的更多相关文章
- windows核心编程 第8章201页旋转锁的代码在新版Visual Studio运行问题
// 全局变量,用于指示共享的资源是否在使用 BOOL g_fResourceInUse = FALSE; void Func1() { //等待访问资源 while(InterlockedExcha ...
- windows核心编程 第5章job lab示例程序 解决小技巧
看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里” 用process explorer程序查看 ...
- windows核心编程---第七章 用户模式下的线程同步
用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...
- Windows核心编程 第十一章 线程池的使用
第11章 线程池的使用 第8章讲述了如何使用让线程保持用户方式的机制来实现线程同步的方法.用户方式的同步机制的出色之处在于它的同步速度很快.如果关心线程的运行速度,那么应该了解一下用户方式的同步机制是 ...
- Windows核心编程 第七章 线程的调度、优先级和亲缘性(下)
7.6 运用结构环境 现在应该懂得环境结构在线程调度中所起的重要作用了.环境结构使得系统能够记住线程的状态,这样,当下次线程拥有可以运行的C P U时,它就能够找到它上次中断运行的地方. 知道这样低层 ...
- Windows核心编程 第六章 线程基础知识 (上)
第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...
- Windows核心编程 第四章 进程(上)
第4章 进 程 本章介绍系统如何管理所有正在运行的应用程序.首先讲述什么是进程,以及系统如何创建进程内核对象,以便管理每个进程.然后将说明如何使用相关的内核对象来对进程进行操作.接着,要介绍进 ...
- Windows核心编程 第三章 内核对象
第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...
- windows核心编程---第五章 线程的基础
与前面介绍的进程一样,线程也有两部分组成.一个是线程内核对象.它是一个数据结构,操作系统用它来管理线程以及用它来存储线程的一些统计信息.另一个是线程栈,用于维护线程执行时所需的所有函数参数和局部变量. ...
随机推荐
- Picgo + Gitee +Typora(自动上传)搭建markdown免费图库
Picgo + Gitee +Typora(自动上传)搭建markdown免费图库 前言: 在写博客的是时候,之前那都是直接在博客网站上面写好了,再一一插入图片,当要在同时2个以上的博客上面发表的 ...
- 关闭ubuntu防火墙
1.关闭ubuntu的防火墙 ufw disable 开启防火墙 ufw enable 2.卸载了iptables apt-get remove iptables 3.关闭ubuntu中的防火墙的其余 ...
- rest framework Genericview
通用视图 Django的通用视图...被开发为普通使用模式的快捷方式......他们采取某些共同的习惯和模式的发展观和抽象,从而使您可以快速地将数据写入的共同看法,而不必重复自己发现的. - Djan ...
- Linux 文件和目录管理
绝对路径:路径的写法一定由根目录/写起的,例如 /usr/local/mysql 相对路径:和绝对路径相反 不是由根目录/写起的,例如用户首先进入到/home,然后进入test 执行命令:cd /ho ...
- 锁与同步器的基础--AQS
什么是AQS AQS全名AbstractQueueSynchronizer,可以翻译为抽象队列同步器 Abstract--说明该类需要被继承,提供实现的框架和一些必要的功能 事实上,AQS也的确提供了 ...
- 从键盘读入学生成绩,找出最高分, 并输出学生成绩等级(Java)
从键盘读入学生成绩,找出最高分, 并输出学生成绩等级 一.题目 从键盘读入学生成绩,找出最高分,并输出学生成绩等级. 成绩>=最高分-10 等级为'A' 成绩>=最高分-20 等级为'B' ...
- 振兴中华(蓝桥杯13年第四届省赛真题 JAVA-B组)
思路:因为只能横向或纵向跳到相邻的格子里,所以到'华'字有两种方法:①从左边的中横向跳过来 ②从上边的中纵向跳过来 直接递推即可. 标题: 振兴中华 小明参加了学校的趣味运动会,其中的一个项目是:跳格 ...
- APIView里如何获取HTTP里的数据
request.data.get() 获取post方法表单里的数据 request.post.get() 获取post方法表单里的数据 request.GET.get() 获取URL里的数据 r ...
- 【LiteOS】LiteOS消息队列
目录 前言 链接 参考 笔录草稿 基本概念 队列运作机制 队列运作原理 消息队列传输方式 消息队列的阻塞机制 出队阻塞 入队阻塞 任务相关函数 任务开发流程 注意事项 * 实战 前言 链接 LiteO ...
- Python 实现自动化 Excel 报表
Py 实现自动化Excel报表 好几个月没有写笔记了, 并非没有积累, 而是有点懒了. 想想还是要续上, 作为工作成长的一部分哦. 最近有做一些报表, 但一直找不到一个合适的报表工具, 又实在不想写前 ...