C或者C++开发肯定经常会遇到各种错误码,由于每个错误码只是一个枚举或者一个整形数值,调试或者输出日志的时候,无法知道这个错误码的具体含义,这时候就需要将此错误码解释出来。对于自己定义的错误码,可以通过自己的方式进行解析。对于Windows API的错误码,则需要调用Windows的API进行解析,下面来介绍具体的错误码解析方法。

 


Windows API 错误码解析

调用Windows API失败后,通常需要通过GetLastError来获取对应的错误码,要将此错误码解析为对应的描述信息,则需要调用另外一个Windows API FormatMessage,原型如下:


Windows错误码解析_c++开发 Collapse


Windows错误码解析_c++开发_02

DWORD WINAPI FormatMessage(
_In_ DWORD dwFlags,
_In_opt_ LPCVOID lpSource,
_In_ DWORD dwMessageId,
_In_ DWORD dwLanguageId,
_Out_ LPTSTR lpBuffer,
_In_ DWORD nSize,
_In_opt_ va_list *Arguments
);


Windows错误码解析_c++开发_02


具体的参数意义就不在这里介绍了,直接查看MSDN即可,下面来看一下具体的使用方法示例:


Windows错误码解析_c++开发 Collapse


char msg[1024] = { 0 };
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, 5, LANG_NEUTRAL, msg, _countof(msg), NULL);
cout << msg << endl;


运行程序即可看到对应的错误描述:拒绝访问


Windows异常值解析

程序在运行的时候,难免会产生一些异常,通过Windows的SEH机制可以得到此异常信息,其中会包含一个异常值,比如0xC0000008。如果用上面提到的FormatMessage的方式,获取到的消息是一个字符串,或者无法获取到此异常值的描述。那么如何获取这个异常值的描述呢,仔细看FormatMessage API的MSDN文档,可以看到有这样一个标志:


Windows错误码解析_c++开发 Collapse


FORMAT_MESSAGE_FROM_HMODULE


这个标志的意思是:可以通过其他模块,来解释此异常值或者错误码。

那么什么模块会包含Windows异常值的定义和解释呢,通过谷歌或者MSDN可以知道,是“ntdll.dll”

知道了这些,就可以写程序来解释Windows异常值了,代码如下:


Windows错误码解析_c++开发 Collapse


Windows错误码解析_c++开发_02

char msg[1024] = { 0 };
HMODULE hntdll = LoadLibrary("NTDLL.DLL");
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
hntdll, 0xC0000008, LANG_NEUTRAL, msg, _countof(msg), NULL);
FreeLibrary(hntdll);
cout << msg << endl;


Windows错误码解析_c++开发_02


ErrLook程序

当的程序中确实需要对Windows错误码和Windows异常值进行解析的时候,就可以使用上面的方法进行解析。

但是当我们只是简单的想看看一个错误码的解释的时候,难道还必须写一个程序来解释吗。

微软也考虑到了你正在思考的这一点,所以在安装了VS后,都会附带一个小工具,用来解释错误码,叫做:ErrLook,一般可以在VS的工具菜单中看到,或者可以在“VS目录\Common7\Tools”目录下找到这个程序,如下:

Windows错误码解析_错误码_09

Windows错误码解析_c++开发_10

Windows错误码解析_拒绝访问_11