Windows中的错误处理

Windows中的错误处理

当使用一个WIN API函数时,它会检验参数的有效性,然后再设法去执行任务.如果传递了一个无效参数,或者是由于某种原因使程序无法正确执行,那操作系统就会返回一个值,指明该函数在某种程度上运行失败了.WINDOWS中的函数有5种返回值类型.

VOID   表示这种函数执行不可能失败,或者不必关心其失不失败. WINDOWS函数很少是这种类型. 而我们平时写代码中,也应该尽量写有返回值的函数,除非你真的确定它中途不会出意外.

BOOL 如果运行失败它会返回0,如果成功则是非0. 因此,可以通过检测它的返回值是0还是非0来判断一个函数有没有执行成功. 注意,请不要写出这样的代码 if( ret == TRUE). 这样做是很不安全的,因为BOOL不仅只有0和1.它在windef.h中被定义, typedef int    BOOL;

HANDLE  如果函数失败,通常返回NULL,否则返回HANDLE值,用于标识你可以操作的一个对象. 但是,某些函数的返回值则是INVALID_HANDLE_VALUE, 它被定义为 -1 . SDK文档在介绍每个函数时都说明了其返回值的含义.用的时候要小心. CreateFile就是这样的一个函数.

LONG/DWORD  这个值比较难以处理,通常这是一种返回数量的函数.如果由于某种原因,函数无法对想要的进行计数,那反该函数通常返回0或-1 (这也是根据相关函数而定). 用的时候要格外小心.

另外,WINDOWS 中定义了一套错误代码列表,用由指明当前API执行后的错误信息. 可以通过GetLastError函数来取得.像这样.

#include <Windows.h> #include <stdio.h> int main() { //打开文件 HANDLE hFile = CreateFile("file.txt",0,0,NULL,OPEN_EXISTING,0,NULL); DWORD er= GetLastError(); return 0; }

返回值 er中便存放了CreateFile调用后,系统记录的错误代码. 并且可们可以看到,hFile的值为INVALID_HANDLE_VALUE。

注意:并不是每个API函数的调用都会更改这个错误代码.某些函数在执行成功时就不会修改. 这个要特别注意.

我们可以通过在VC环境下的"监视"窗口中输入  @err,hr  回车后右边的信息窗口中便会显示出当前错误代码对应的信息提示信息.

像上面这个列子,我们将断点设置在 return 0;这一行上,当执行到此后,我们按上面的方法去做. 你会发现监视窗口中会出现如下提示

  @err,hr 0x00000002 系统找不到指定的文件。

当然,我们也可以通过错误代码输出格式化字符串,下面的函数可以做到这一点.

DWORD FormatMessage(

     DWORD dwFlags,

     LPVOID  pSource,

     DWORD dwMessageId,

     DWROD dwLanguageId,

     PTSTR pszBuffer,

     DWORD nSize;

     va_list *Arguments);

这个函数的功能非常强大,可以在多种语言中进行操作.

#include <Windows.h> #include <stdio.h> int main() { //打开文件 HANDLE hFile = CreateFile("file.txt",0,0,NULL,OPEN_EXISTING,0,NULL); DWORD er= GetLastError(); HLOCAL local; CHAR* buffer[256]; // FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,NULL, // er,MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),(PTSTR)&local,0,NULL); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,NULL, er,MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),(PTSTR)&local,0,NULL); printf("%s",(PCTSTR)LocalLock(local)); getchar(); return 0; }

被注释的部分是用英语输出,而刚刚都说了,这个东西支持多国语言,于是下面就淙了支持中文的做法。 需要说明的是,这个函数的功能非常多。 刚刚仅是演示了从系统和本地BUFFER中取得错误信息。


#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
#define FORMAT_MESSAGE_IGNORE_INSERTS  0x00000200
#define FORMAT_MESSAGE_FROM_STRING     0x00000400
#define FORMAT_MESSAGE_FROM_HMODULE    0x00000800
#define FORMAT_MESSAGE_FROM_SYSTEM     0x00001000
#define FORMAT_MESSAGE_ARGUMENT_ARRAY  0x00002000
#define FORMAT_MESSAGE_MAX_WIDTH_MASK  0x000000FF

从它强大的定义可以看出来,支持的东西挺多的。  比如下面的组合:

FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM 则可 以用于网络相关的错误。。

同样的,用户也可以自己定义错误代码。 错误代码是一个32位的值。

31-30 位,标志错误的严重性。  0 = 成功    1 = 供参考    2 = 警告    3 = 错误

29 位,则标志着错误提供者, 0 表示由MS自己提供, 1 表示由用户提供。所以,用户自定的代码,其29位必需为1。

28 位,保留,必须为0。

27-16 位, 由MS公司定义,标志设备代码。

15-0 位,则是异常代码,MS和客户均要使用此位。

posted @ 2010-06-24 09:13 麒麟子(Alex) 阅读( ...) 评论( ...) 编辑 收藏
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值