《windows核心编程系列》一谈谈windows中的错误处理机制
错误处理
我们写的函数会用返回值表示程序执行的正确与否,使用void,就意味着程序一定不会出错。Bool类型标识true时为真,false时为假。其他类型根据需要可以定义成不同意义。
Windows除了使用返回值标识函数执行情况,外还引入了错误代码机制。返回值指出函数已发生一个错误。要查看具体是什么错误,就应该使用错误代码。如当我们调用函数打开一个文件,如果打开失败,可能出现多种原因。一是:文件不存在,另一种是该文件被其他程序互斥使用。在这两种情况下都导致文件打开失败,返回值仅仅标识打开失败,但我们不知道原因。这时错误代码就派上用场了。
Windows将错误代码存储于独立于线程的,线程局部存储区中。顾名思义,这个区域是每个线程独有的其他线程无法更改。它存储着一些线程独有的东西,在第二十一章有详细的介绍。在函数执行后,就可以通过调用GetLastError()来获得错误代码。因此这个错误代码永远反映的是上一个函数的执行情况,也就是说它的值是由上一个函数设置的。这就难免发生错误代码被覆盖的情况。如果调用一个函数后,没调用GetLastError就调用其他函数,此时GetLastError返回的是第二个函数的执行情况,而不是第一个,这个要注意。
- DWORD GetLastError();
由函数原型可以知道该函数返回一个DWROD类型的变量。这仅仅是个数字啊,就像当你要访问一个页面,啥也不说就来个404,对于我们来说不成问题,我们知道这是页面不存在或链接错误。但是对于客户来说可能会一脸茫然,以为是电脑坏了呢。404你是知道,610 ,611,612你知道吗?哈哈,这难不到我们程序员兄弟们,网上一搜全搞定。如果不能上网搜你怎么解决呢。
对于GetLastError返回的错误代码,我们不需要考虑这些问题。 VS给我们提供了一个小工具可以将错误代码转换为相应的文本描述。工具--》ErrorLookup。Windows为每个错误代码定义一个宏,
如 #define ERROR_SUCCESS 0L
#define ERROR_INVALID_FUNCTION 1L
#define ERROR_FILE_NOT_FOUND 2L
..........
有了这些宏,只看字面意思都可以知道它到底表示的什么意思,而不用死记硬背这些毫无规律的数字了。
一个错误代码对应着一段文本描述,详细的描述错误原因。当我们在自己的程序中检测到一个错误,我们可能需要向用户显示错误的文本描述,而不是一个干巴巴的错误代码,让用户自己去查毕竟不是个好主意。Windows提供一个函数,FormatMesssage可以返回传入的错误代码对应的字符串的首地址。此函数及以后遇到的函数的使用方法不会详细介绍,使用时搜下便知,现在只知道有这样一个函数就可以了。
调用GetLastError仅仅是返回windows定义的错误代码,除此之外windows允许这种机制用于我们自己的函数中。比如,我们写了一个函数供别人调用,可以返回false表示调用失败,还可以使用错误代码来提供更多的信息。通过使用SetLastError可以设置我们认为合适的值。它将线程局部存储区的错误代码设置为我们传递的值,此后调用GetLastError返回的就是我们刚刚设置的值。
Windows.h中定义了256个错误代码用以标识256种错误情况,我们在调用SetLastError时,可以传入windows定义过得大部分错误代码,毕竟256中错误情况包含了绝大部分情况。如果所有这些都不能反映你的情况,你可以传入大于255的数作为错误代码。大于255的值是windows留给程序员使用的。
调试程序时,对上一个错误代码进行监视是很有用的。可以在watch窗口中输入$err,hr。它会在value一列显示当前线程的上一个错误代码和该值对应的文本描述。注意是当前线程的哦!!
总结:本章很简单,只需记住GetLastError,FormatMessage,SetLastError就差不多了。
《windows核心编程系列》一谈谈windows中的错误处理机制的更多相关文章
- windows核心编程---第一章 谈谈windows中的错误处理机制
我们写的函数会用返回值表示程序执行的正确与否,使用void,就意味着程序一定不会出错.Bool类型标识true时为真,false时为假.其他类型根据需要可以定义成不同意义. Win ...
- 《windows核心编程系列》十八谈谈windows钩子
windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...
- 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...
- 《Windows核心编程系列》二十谈谈DLL高级技术
本篇文章将介绍DLL显式链接的过程和模块基地址重定位及模块绑定的技术. 第一种将DLL映射到进程地址空间的方式是直接在源代码中引用DLL中所包含的函数或是变量,DLL在程序运行后由加载程序隐式的载入, ...
- 《windows核心编程系列》十七谈谈dll
DLL全称dynamic linking library.即动态链接库.广泛应用与windows及其他系统中.因此对dll的深刻了解,对计算机软件开发专业人员来说非常重要. windows中所有API ...
- 《windows核心编程系列》二谈谈ANSI和Unicode字符集 .
http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理 使用vc编程时项目-->属性-->常 ...
- 《windows核心编程系列》二十一谈谈基址重定位和模块绑定
每个DLL和可执行文件都有一个首选基地址.它表示该模块被映射到进程地址空间时最佳的内存地址.在构建可执行文件时,默认情况下链接器会将它的首选基地址设为0x400000.对于DLL来说,链接器会将它的首 ...
- 《windows核心编程系列》十六谈谈内存映射文件
内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...
- 《Windows核心编程系列》十四谈谈默认堆和自定义堆
堆 前面我们说过堆非常适合分配大量的小型数据.使用堆可以让程序员专心解决手头的问题,而不必理会分配粒度和页面边界之类的事情.因此堆是管理链表和数的最佳方式.但是堆进行内存分配和释放时的速度比其他方式都 ...
随机推荐
- SyntaxError: expected expression, got '<'异常错误
引入jQuery文件,浏览器报SyntaxError: expected expression, got '<'错误,但是jQuery文件可以在网络一栏看到,最后检查是springMVC定义的拦 ...
- Spring中基于AOP的@AspectJ
以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...
- hp 88a加粉
http://v.youku.com/v_show/id_XNzEzODEwNzMy.html
- Cg入门6:函数2
内建函数分为四类: 1.数学函数 2.几何函数 3.纹理函数 4.导数函数:事实上就是片段函数
- C\C++中strcat()函数、sprintf函数
http://blog.csdn.net/smf0504/article/details/52055971 http://c.biancheng.net/cpp/html/295.html
- win10 localhost 解析为::1 的解决办法
win10 localhost 解析为::1 的解决办法 学习了:https://blog.csdn.net/ambertian/article/details/70238020
- There is no PasswordEncoder mapped for the id "null"
There is no PasswordEncoder mapped for the id "null" 学习了:https://blog.csdn.net/dream_an/ar ...
- C++开发人脸性别识别教程(8)——搭建MFC框架之读取目录信息
在上一篇博客中我们已经绘制了MFC界面,在这篇博客中我们将加入响应代码,为MFC框架加入一个最主要的功能:打开一个目录. 一.加入相关头文件 这里头文件主要包括三类:opencv头文件.批量读取文件相 ...
- css 滤镜之Gradient
CreateTime--2017年12月26日11:09:14 Author:Marydon ie滤镜特效之Gradient 作用: 用于设置渐变背景色 使用条件: IE9及以下版本不支持属性ba ...
- router-link的a样式变成div样式元素属性
<router-link tag="div" :to="itemChild.path"><span>{{itemChild.name}} ...