【Windows 核心编程】Windows 核心编程 -- 错误处理
2012-11-12 10:51
465 查看
一,常见的Windows函数返回值类型
1)VOID:这个函数不可能失败,极少数Windows函数的返回值类型为VOID。
VOID ExitProcess(UINT uExitCode);
2)BOOL:如果函数失败,返回值为0;否则,返回值是一个非0值。应避免测试返回值是否为TRUE,应该检查是否不为FALSE。
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
为什么不能使用if (result == TRUE),而要使用if (result != FALSE)。从反汇编代码的效率以及指令长度上没有什么区别。
但是主要在0、1的判断,0是单独个体,但是1需要理解为非0就对了,但是机器只是跟1来比较,所以缩小了范围。
3)HANDLE:如果函数失败,返回值通常为NULL;否则HANDLE将标识一个可以操作的对象。但是有时候失败的时候返回的值为INVALID_HANDLE_VALUE,被定义为-1。
HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
4)PVOID:如果函数调用失败,则返回值为NULL;否则PVOID将标识一个数据块的内存地址
5)LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
6) LONG/DWORD:返回具体的LONG/DWORD数值,需要根据MSDN的提示进行正确判断。
7)DWORD GetCurrentProcessId(VOID);
二,函数错误返回码
Windows函数检测到错误的时候,它会使用一种名为“线程本地存储区”的机制将相应的错误代码与调用线程关联到一起,使得不同线程的错误代码不互相干扰。
GetLastError()
此函数的作用很简单,就是返回由上一个函数调用设置的线程的32位错误码。WinError.h头文件包含了MiscrSoft定义的错误代码列表。
Windows函数调用失败之后,要马上调用该函数,不然可能在调用了另一个Windows函数后,LastError将会被改写(Windows函数调用成功以后可能会把此值改写成ERROR_SUCCESS)。
之前见过一下两种方法,使用GetLastError(),都应该在后续编程时尽量将程序的容错性、健壮性提高。
代码 1:
代码 2:
switch (GetLastError())
{
case ERROR_IO_PENDING:
//...
break;
case ERROR_PIPE_CONNECTED:
//...
break;
default:
{
printf("Connent Namepipe failed with %d.\n", GetLastError());
return 0;
}
}
代码 3:
三,定义自己的错误代码
1)对于自己写的函数也可以通过API设置错误号,增强健壮性,使用SetLastError(),便可以修改错误号,不过为了通用,对于设置错误代码尽量使用WinError.h中的。也可以自己设置新的错误编号。
VOID SetLastError(DWORD dwErrCode)
32位错误代码
四,VS的Debug调试信息
在VS的Watch窗口中,添加$err,hr就可以显示函数错误返回码和相关提示语句,已经错误提示。VC6不支持。
五,ErrorShow程序
FormatMessage( ) //将GetLastError得到的错误信息(这个错误信息是数字代号)转化成字符串信息的函数
1)函数原型:
DWORD WINAPI FormatMessage(
__in DWORD dwFlags, //标志位,决定如何说明lpSource参数
__in_opt LPCVOID lpSource,
__in DWORD dwMessageId, //请求的消息的标识符。当dwFlags标志为FORMAT_MESSAGE_FROM_STRING时会被忽略
__in DWORD dwLanguageId, //请求的消息的语言标识符
__out LPTSTR lpBuffer, //缓存区保存格式化消息,通过lpBuffer 指向首地址
__in DWORD nSize, //如果FORMAT_MESSAGE_ALLOCATE_BUFFER标志没有被指定,这个参数必须指定为输出缓冲区的大小
__in_opt va_list *Arguments // 保存格式化信息中的插入值的一个数组。
);
返回值:
如果函数调用成功,返回输出缓冲区的大小,除最后一个空字符。如果失败侧返回0。
2)代码示例:
#include <stdio.h>
#include <windows.h>
int main()
{
DWORD dwError = 0;
printf("请输入要查询的错误代码:");
scanf("%d", &dwError);
HLOCAL hLocal = NULL;
DWORD SystemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
dwError, //请求的消息的消息标识符
SystemLocale, //语言标识符
(PTSTR)&hLocal, //缓冲区保存格式化消息,并且通过lpBuffer指向该地址。
0,
NULL);
if(hLocal!=NULL)
{
MessageBox(NULL,(PCTSTR)LocalLock(hLocal),L"Title(错误内容)",MB_OK);
// LocalLock(hLocal);
}
printf("查询失败:没有对应错误代码\n");
getchar();
return -1;
}
1)VOID:这个函数不可能失败,极少数Windows函数的返回值类型为VOID。
VOID ExitProcess(UINT uExitCode);
2)BOOL:如果函数失败,返回值为0;否则,返回值是一个非0值。应避免测试返回值是否为TRUE,应该检查是否不为FALSE。
BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
为什么不能使用if (result == TRUE),而要使用if (result != FALSE)。从反汇编代码的效率以及指令长度上没有什么区别。
但是主要在0、1的判断,0是单独个体,但是1需要理解为非0就对了,但是机器只是跟1来比较,所以缩小了范围。
3)HANDLE:如果函数失败,返回值通常为NULL;否则HANDLE将标识一个可以操作的对象。但是有时候失败的时候返回的值为INVALID_HANDLE_VALUE,被定义为-1。
HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
4)PVOID:如果函数调用失败,则返回值为NULL;否则PVOID将标识一个数据块的内存地址
5)LPVOID HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
6) LONG/DWORD:返回具体的LONG/DWORD数值,需要根据MSDN的提示进行正确判断。
7)DWORD GetCurrentProcessId(VOID);
二,函数错误返回码
Windows函数检测到错误的时候,它会使用一种名为“线程本地存储区”的机制将相应的错误代码与调用线程关联到一起,使得不同线程的错误代码不互相干扰。
GetLastError()
此函数的作用很简单,就是返回由上一个函数调用设置的线程的32位错误码。WinError.h头文件包含了MiscrSoft定义的错误代码列表。
Windows函数调用失败之后,要马上调用该函数,不然可能在调用了另一个Windows函数后,LastError将会被改写(Windows函数调用成功以后可能会把此值改写成ERROR_SUCCESS)。
之前见过一下两种方法,使用GetLastError(),都应该在后续编程时尽量将程序的容错性、健壮性提高。
代码 1:
if (!WriteFile(hFile, lpBuffer, strlen(lpBuffer), &dwWritten, NULL)) { return GetLastError( ); }
代码 2:
switch (GetLastError())
{
case ERROR_IO_PENDING:
//...
break;
case ERROR_PIPE_CONNECTED:
//...
break;
default:
{
printf("Connent Namepipe failed with %d.\n", GetLastError());
return 0;
}
}
代码 3:
if(ERROR_INSUFFICIENT_BUFFER == GetLastError()) { lpDeviceInterfaceDetailData = HeapReAlloc( GetProcessHeap(), 0, lpDeviceInterfaceDetailData, dwBufferSize); lpDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); }
三,定义自己的错误代码
1)对于自己写的函数也可以通过API设置错误号,增强健壮性,使用SetLastError(),便可以修改错误号,不过为了通用,对于设置错误代码尽量使用WinError.h中的。也可以自己设置新的错误编号。
VOID SetLastError(DWORD dwErrCode)
32位错误代码
四,VS的Debug调试信息
在VS的Watch窗口中,添加$err,hr就可以显示函数错误返回码和相关提示语句,已经错误提示。VC6不支持。
五,ErrorShow程序
FormatMessage( ) //将GetLastError得到的错误信息(这个错误信息是数字代号)转化成字符串信息的函数
1)函数原型:
DWORD WINAPI FormatMessage(
__in DWORD dwFlags, //标志位,决定如何说明lpSource参数
__in_opt LPCVOID lpSource,
__in DWORD dwMessageId, //请求的消息的标识符。当dwFlags标志为FORMAT_MESSAGE_FROM_STRING时会被忽略
__in DWORD dwLanguageId, //请求的消息的语言标识符
__out LPTSTR lpBuffer, //缓存区保存格式化消息,通过lpBuffer 指向首地址
__in DWORD nSize, //如果FORMAT_MESSAGE_ALLOCATE_BUFFER标志没有被指定,这个参数必须指定为输出缓冲区的大小
__in_opt va_list *Arguments // 保存格式化信息中的插入值的一个数组。
);
返回值:
如果函数调用成功,返回输出缓冲区的大小,除最后一个空字符。如果失败侧返回0。
2)代码示例:
#include <stdio.h>
#include <windows.h>
int main()
{
DWORD dwError = 0;
printf("请输入要查询的错误代码:");
scanf("%d", &dwError);
HLOCAL hLocal = NULL;
DWORD SystemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
BOOL bOk = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL,
dwError, //请求的消息的消息标识符
SystemLocale, //语言标识符
(PTSTR)&hLocal, //缓冲区保存格式化消息,并且通过lpBuffer指向该地址。
0,
NULL);
if(hLocal!=NULL)
{
MessageBox(NULL,(PCTSTR)LocalLock(hLocal),L"Title(错误内容)",MB_OK);
// LocalLock(hLocal);
}
printf("查询失败:没有对应错误代码\n");
getchar();
return -1;
}
相关文章推荐
- 读Windows核心编程-1-错误处理
- 函数错误处理二(总结自己windows编程核心)
- windows 核心编程之 错误处理 -----学习笔记
- 函数错误处理一(总结自windows编程核心)
- Windows核心编程-错误处理
- Windows核心编程--错误处理/字符/字符串
- windows核心编程--函数返回错误
- WINDOWS核心编程学习笔记--字符串处理
- C++ 编程处理字符串经常出错,我自己接管了Windows的那个错误报告
- Windows核心编程----处理结构化异常处理(SEH)和C++提供的异常处理不相同
- windows核心编程心解--错误机制
- windows 核心编程 (终止处理程序)
- ASP.NET 3.5核心编程学习笔记(8):错误处理、页面跟踪
- window核心编程学习笔记 (一) 错误处理以及Unicode
- 【Windows 核心编程】Windows 核心编程 -- 字符和字符串处理
- windows核心编程心解--字符和字符串处理
- java编程思想 bruce Eckel chapter12 通过异常处理错误-chapter22 图形化用户界面
- (windows编程 学习笔记一) 结构化异常处理(结束处理)
- IOS网络编程之错误处理
- 10 错误和异常 - 《Python 核心编程》