这一节东西比较少,本应该归并在上一节里,但是昨天太晚了。就先把那些东西分为上了。这节里面就一个问题,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 ++异常(下)的更多相关文章

  1. windows核心编程 第8章201页旋转锁的代码在新版Visual Studio运行问题

    // 全局变量,用于指示共享的资源是否在使用 BOOL g_fResourceInUse = FALSE; void Func1() { //等待访问资源 while(InterlockedExcha ...

  2. windows核心编程 第5章job lab示例程序 解决小技巧

    看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里”         用process explorer程序查看 ...

  3. windows核心编程---第七章 用户模式下的线程同步

    用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...

  4. Windows核心编程 第十一章 线程池的使用

    第11章 线程池的使用 第8章讲述了如何使用让线程保持用户方式的机制来实现线程同步的方法.用户方式的同步机制的出色之处在于它的同步速度很快.如果关心线程的运行速度,那么应该了解一下用户方式的同步机制是 ...

  5. Windows核心编程 第七章 线程的调度、优先级和亲缘性(下)

    7.6 运用结构环境 现在应该懂得环境结构在线程调度中所起的重要作用了.环境结构使得系统能够记住线程的状态,这样,当下次线程拥有可以运行的C P U时,它就能够找到它上次中断运行的地方. 知道这样低层 ...

  6. Windows核心编程 第六章 线程基础知识 (上)

    第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...

  7. Windows核心编程 第四章 进程(上)

    第4章 进 程     本章介绍系统如何管理所有正在运行的应用程序.首先讲述什么是进程,以及系统如何创建进程内核对象,以便管理每个进程.然后将说明如何使用相关的内核对象来对进程进行操作.接着,要介绍进 ...

  8. Windows核心编程 第三章 内核对象

    第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...

  9. windows核心编程---第五章 线程的基础

    与前面介绍的进程一样,线程也有两部分组成.一个是线程内核对象.它是一个数据结构,操作系统用它来管理线程以及用它来存储线程的一些统计信息.另一个是线程栈,用于维护线程执行时所需的所有函数参数和局部变量. ...

随机推荐

  1. Java中遍历集合的常用方法

    一.List 1.普通for循环 for (int i = 0; i < list.size(); i++)){ String temp = (String)list.get(i); Syste ...

  2. Docker上安装Redis

    Docker可以很方便的进行服务部署和管理,下面我们通过docker来搭建Redis的单机模式.Redis主从复制.Redis哨兵模式.Redis-Cluster模式 一.在Docker上安装单机版R ...

  3. 实践解析丨Rust 内置 trait:PartialEq 和 Eq

    摘要:Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性. Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 S ...

  4. Kubernetes声明式API与编程范式

    声明式API vs 命令时API 计算机系统是分层的,也就是下层做一些支持的工作,暴露接口给上层用.注意:语言的本质是一种接口. 计算机的最下层是CPU指令,其本质就是用"变量定义+顺序执行 ...

  5. A. 1.划分数列

    A . 1. 划 分 数 列 A. 1.划分数列 A.1.划分数列 氵水沝淼㵘解析 先预处理,然后公式推(详见代码) Code #include <bits/stdc++.h> using ...

  6. CVE-2010-3333-office RTF栈溢出漏洞分析

    0x00 前言 此漏洞是根据泉哥的<漏洞战争>来学习分析的,网上已有大量分析文章在此只是做一个独立的分析记录. 0x01 复现环境 操作系统-->windows7 x64 软件版本- ...

  7. 有关指针和C语言中的常量

    常量类型(五种): 字面常量(2,3,6....) ;                           enum 定义的枚举常量; 字符常量('a','b'....) ;              ...

  8. 整合一套高性能网关Kong

    前言 相信大家对Api网关都比较的熟悉,我们之前的文章也介绍过ASP.NET Core的网关Ocelot,也介绍过Spring Cloud Gateway.说到网关的主要功能,其实总结起来就两个字&q ...

  9. 【Java】 6.0 输入,输出和异常处理

    [概述] 就目前而言,我们遇到的"输出"无非就是这个比: System.out.println() 更详细的输入输出会在IO中提到,那么这个笔记就是记录几种常用输入机制 [Scan ...

  10. 如何用 Electron + WebRTC 开发一个跨平台的视频会议应用

    在搭建在线教育.医疗.视频会议等场景时,很多中小型公司常常面临 PC 客户端和 Web 端二选一的抉择.Electron 技术的出现解决了这一难题,只需前端开发就能完成一个跨平台的 PC 端应用.本文 ...