c异常和windows结构异常的比较

上传人:xiao****1972 文档编号:84137395 上传时间:2019-03-02 格式:DOC 页数:20 大小:226.85KB
返回 下载 相关 举报
c异常和windows结构异常的比较_第1页
第1页 / 共20页
c异常和windows结构异常的比较_第2页
第2页 / 共20页
c异常和windows结构异常的比较_第3页
第3页 / 共20页
c异常和windows结构异常的比较_第4页
第4页 / 共20页
c异常和windows结构异常的比较_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《c异常和windows结构异常的比较》由会员分享,可在线阅读,更多相关《c异常和windows结构异常的比较(20页珍藏版)》请在金锄头文库上搜索。

1、查看文章try . catch 与 _try . _except2009-09-24 11:43VC中的这两个东西肯定谁都用过, 不过它们之间有什么区别, 正好有时间研究了一下, 如果有错误欢迎拍砖.基于VC2005, 32位XP 平台测试通过. 估计对于其他版本的VC和操作系统是不通用的.1. try . catch这个是C+语言定义的, 每个C+都有对其的不同的实现. 使用也很简单. 比如我们有一个函数, 读入年龄. 如果=100, 抛出异常:int readAge() int age = 读入年龄; if (age = 100) throw AgeException(age); retu

2、rn age;其中 AgeException 的定义为class AgeException public: int errorAge; AgeException(int age) errorAge = age; ;在使用的时候也比较简单,try int i = readAge(); printf(Age inputed is %d, i); catch (AgeException e) printf(error. Age inputed = %d and is not valid., e.errorAge);2. _try . _except这个是VC自己定义的不是C+的关键字. VC在编译_

3、try . _except的时候, 会按照Windows SEH(结构化异常)处理的规则, 把异常处理部分加入到当前线程的异常处理链中. 这部分不详细写了, SEH处理在网上的文章一搜一大把.3. try.catch 与 _try . _except 使用上的区别对于上面的AgeException, 我们也可以使用_try. _except 来处理:_try int i = readAge(); printf(Age inputed is %d, i); _except (EXCEPTION_EXECUTE_HANDLER) printf(Age is not correct.);但是, 对于

4、_try . _except 能够处理的异常(比如下面的代码), C+异常处理try . catch 不能够捕获(Catch段不能执行):try int *p = NULL; *p = 0; catch (.) printf(Exception occured.);注: 这里其实和编译器有关, VC2005由/EH加上参数来控制, 详情参见http:/ . 这里讨论的是默认的情况, 不处理的时候.这是为什么呢. 仔细看了下, 当我们在程序里面throw出来一个异常的时候, 调试器(比如VC, WinDBG)会记录下面一个事件:First-chance exception at 0x7c812a

5、fb (kernel32.dll) in trycatch.exe: Microsoft C+ exception: AgeException at memory location 0x0012fc98.也就是说, 在VC中, throw出来的都是Microsoft C+ exception. 只有这种Exception才能被try.catch捕获. 同样, 用WinDBG装载上面的程序_try int i = readAge(); printf(Age inputed is %d, i); _except (EXCEPTION_EXECUTE_HANDLER) printf(Age is n

6、ot correct.);会发现, 出现的异常为C+ exception, 异常代码为0xe06d7363:也就是说, 在C+中throw出来的异常是一种特殊的类型的异常, 是微软专门为VC+实现的,异常代码为0xe06d7363. (有意思的是ASCII码为0x6d, 0x73, 0x63的字符为msc)到这里我们基本可以得出一个结论, try.catch和_try._except其实从本质上来说是一回事, 他们从根源上来说都是用到了Windows的SEH处理机制. 不同点在于:-) try.catch 只处理异常代码为0xe06d7363的C+ exception, 不会理会其他的;-)

7、try.catch 对于编译器来说做了一些额外的工作, 但是最终的实现是和_try._except都要归结于SEH-) try.catch 多了一些额外的传递具体的异常信息的部分(catch的是何种异常. 不像是_try._except, 需要用ExceptionCode去判断)想到这, 想到了下面一个问题, 就是VC+编译器是如何知道catch的异常信息的呢? 换句话说, 对于下面的代码, 我们知道出现了异常, 但是怎么得到异常的信息的呢?_try int i = readAge(); printf(Age inputed is %d, i); _except (EXCEPTION_EXEC

8、UTE_HANDLER) printf(Age is not correct.); /如何知道readAge中throw出来的AgeException?为了调试方便, 把异常类和抛出异常的代码修改一下, 在创建异常的时候传递错误的age和一条消息class AgeException public: int errorAge; char *p; AgeException(int age, char* msg) errorAge = age; p = msg; ;int readAge() int age = 123; / if (age = 100) throw AgeException(age

9、, Age is outof range.); return age;用WinDBG装入, 运行, 出现了C+异常后, 使用.exr -1 命令查看最近出现的异常:可以看出, 这个异常为前面讨论的C+异常(0xe06d7363类型), 带有3个参数, 每个参数, 参数分别为0x19930520, 0x0012fca4, 0x00417bc8. 因为我没有找到C+异常中参数的含义, 只能猜了(哪位如果知道请赐教). 考虑到抛出异常的代码抛出的异常类型为AgeException, 那么很自然想到抛出的异常作为一个指针存储在参数中. 因为没有资料, 只能挨个试验了. 使用命令dt trycatch!

10、AgeException 地址, 来把trycatch模块(编译出的程序名是trycatch.exe)中地址的内容按照类AgeException显示出来:果然, 第一个参数0x19930520里面是不是我们想要的; 当输入第二个参数的时候, 该地址中的内容和预料的一致, 是我们抛出的异常中的内容. 这样验证了猜想. try.catch的工作流程为:-) 编译器在编译try.catch的时候, 也是利用Windows的SEH, 只不过仅仅针对C+异常(0xe06d7363类型)进行处理;-) 抛出异常的时候(throw), 把生成的异常类的实例地址, 保存在异常信息的第二个参数中-) catch

11、异常的时候, 从异常信息第2个参数中读出地址, 并转化为异常类的实例, 供程序使用.要使用_try._except模拟上述的过程, 程序可以改为:_try int i = readAge(); printf(Age inputed is %d, i); _except (extract(GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) printf(Exception happene.);void extract(LPEXCEPTION_POINTERS p) int d = p-ExceptionRecord-NumberParame

12、ters; /参数数目, 这里没用到 unsigned int * ex = (unsigned int *) p-ExceptionRecord-ExceptionInformation1; /第二个参数 AgeException * e = (AgeException *) ex; /转换,得到异常类的实例 printf(= %d n, e-errorAge); /异常的信息可以知道了. printf(= %s n, e-p); /异常的信息可以知道了.运行, 和预期的结果是一致的.最后可以得到结论(不知道这样说是否完全正确) :try.catch是编译器对_try . _except的一

13、个包装; 该包装仅处理C+异常类型, 但是提供了比较方便的方法来传递抛出的异常信息, 这样程序员能够比较方便的处理异常, 而不用想上面的例子那样要手工去异常信息中去取.相册 留言 用户操作 留言 发消息 加为好友 陈明亮ID:cml2030共10649次访问,排名15936,好友18人,关注者16人。陈明亮的文章原创 44 篇翻译 0 篇转载 12 篇评论 7 篇订阅我的博客 编辑cml2030的公告 因为工作原因,编程语言常常要切换,需要一个博客整理一下基础知识,备忘. 技术交流QQ:5862177 (注:CSDN) 编辑文章分类 ActiveXASP.NETC#与.NETC/C+语言Del

14、phiVC/MFCWindows 编程基础Windows 网络编程其它存档 2010年12月(6)2010年11月(3)2010年09月(1)2010年08月(4)2010年04月(1)2010年03月(1)2010年02月(2)2009年12月(2)2009年11月(1)2009年07月(2)2009年06月(2)2009年04月(1)2009年03月(1)2008年12月(3)2008年10月(6)2008年09月(1)2008年07月(1)2008年06月(3)2008年03月(15)公告: 2011年4月微软MVP申请开始啦!有兴趣的抓紧时间哦! 意见反馈官方博客 C+异常与windows结构化异常处理简单说明 收藏 一、C+标准异常t

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 大杂烩/其它

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号