1. Windows函数错误处理步骤:调用Windows函数时,它会先验证我们传给它的参数,然后再开始执行任务.如果传入的参数无效,或者由于其他原因导致操作无法执行,则函数的返回值将指出函数因为某些原因失败了.Windows函数的常见返回值:
数据类型 | 指出函数调用失败的值 |
VOID | 这个函数不可能失败.只有极少数Windows函数的返回值类型为VOID |
BOOL | 如果函数失败,返回值为0;否则返回值为非零.应避免测试返回值是否为TRUE;最稳妥的做法是检查它是不是FALSE |
HANDLE | 如果函数失败,则返回值通常是NULL,否则HANDLE将 标识一个可操纵的对象.请注意这种返回值,因为某些函数会返回INVALID_HANDLE_VALUE的一个句柄值,它被定义为-1.函数的Platform SDK文档清楚说明了函数是返回NULL还是INVALID_HANDLE_VALUE来标识失败 |
LPVOID | 如果调用失败,则返回NULL,否则LPVOID将标识一个数据块的内存地址 |
LONG/DWORD | 这种问题比较棘手.返回计数的函数会通常会返回一个LONG或DWORD.如果函数处于某种原因不能对我们想要计数的东西进行计数,它通常返回0或-1(具体取决于函数).如果要调用一个返回LONG/DWORD的函数,务必仔细阅读文档,确保我们会正确的检查可能出现的错误 |
2. 在内部,当Windows函数检测到错误时,它会使用一种名为”线程本地存储区”的机制将相应的错误代码与”主调线程”(或者说发出调用的线程,即calling thread)关联到一起.这种机制是不同的线程能独立运行,不会出现相互干扰对方的错误代码的情况.函数返回时,其返回值已指出发生了一个错误.要查看具体什么错误,您得调用:DWORD GetLastError()
Windows函数调用失败之后应该马上调用GetLastError,因为假设又调用了另一个Windows函数,则此值很可能被改写.注意成功调用的Windows函数可能用ERROR_SUCCESS改写该值.
一些Windows函数调用成功可能源于不同的原因.为返回这种信息,Microsoft选择采用”上一个错误代码”机制.所以特定函数调用成功时,可以调用GetLastError来确定额外的信息.对于具有这种行为的函数,Platform SDK文档会清楚指明能以这种方式调用GetLastError.
3. 为了显示错误的文本描述,而非编号,可以调用FormatMessage:
DWORD FormatMessage(
DWORD dwFlags,//标志位
LPCVOID pSource,//参数
DWORD dwMessageId,//消息ID
DWORD dwLanguageId,//语言ID
PTSTR pszBuffer,//返回的字符串
DWORD nSize,//字符串的大小
va_list * Arguments);//通常不使用
参数:
dwFlags:
FORMAT_MESSAGE_ALLOCATE_BUFFER //此函数会分配内存以包含描述字串。
FORMAT_MESSAGE_FROM_SYSTEM, // 在系统的id映射表中寻找描述字串
FORMAT_MESSAGE_FROM_HMODULE // 在其他资源模块中寻找描述字串
FORMAT_MESSAGE_FROM_STRING // 消息ID是个字串,不是个DWORD
通常为:FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
lpSource:
# 指定了FORMAT_MESSAGE_FROM_HMODULE的话,此参数表示模块的HANDLE
# 指定了FORMAT_MESSAGE_FROM_STRING的话,此参数表示id字串
通常为:NULL
dwMessageId:
消息ID;如果指定FORMAT_MESSAGE_FROM_STRING,将被忽略。
dwLanguageId:
消息描述所用的语言
通常为:0表示自动选择
lpBuffer:
#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,则为自己提供的缓冲区
#否则为系统LocalAlloc分配,需要被用户LocalFree
nSize:
#如果未指定FORMAT_MESSAGE_ALLOCATE_BUFFER,则为自己提供的缓冲区大小
#否则为系统LocalAlloc分配之最小缓冲区大小
Arguments:
通常不使用
4.错误代码的不同字段:
位 | 31-30 | 29 | 28 | 27-16 | 15-0 |
内容 | 严重性 | Microsoft/客户 | 保留 | Facility代码 | 异常代码 |
含义 | 0=成功 1=信息 2=警告 3=错误 | 0=Microsoft定义的代码 1=客户定义的代码 | 必须为0 | 前256个值由Microsoft保留 | Microsoft/客户定义的代码 |
注:Microsoft承诺,在它所生成的所有错误代码中此位始终为0.但是如果我们自己要定义自己的错误代码,就必须将此位放入一个1.