WinAPI FormatMessage返回错误码8/87的问题排查求助
问题解决步骤
1. 核心错误分析
- 最初触发错误码8(ERROR_NOT_ENOUGH_MEMORY)的原因:使用
FORMAT_MESSAGE_ALLOCATE_BUFFER标志时,FormatMessage需要接收指向字符串指针的指针(即LPTSTR*)来存储分配的内存地址,直接传递lpMsgBuf会导致参数非法,触发内存相关错误。 - 修改后出现错误码87(ERROR_INVALID_PARAMETER)的原因:UNICODE环境下
LPTSTR是wchar_t*类型,wprintf输出宽字符串需要用%ls格式符,而非用于窄字符串的%s,格式符不匹配导致参数错误。
2. 修正后的完整代码
static inline void printLastMessage() { LPTSTR lpMsgBuf = NULL; DWORD err = GetLastError(); printf("Error code: %u\n", err); DWORD formatResult = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, // 使用ALLOCATE_BUFFER时,此参数指定最小分配字符数,0表示让函数自动计算 NULL ); if (formatResult == 0) { printf("FormatMessage failed, error code: %u\n", GetLastError()); return; // 分配失败时直接返回,避免访问空指针 } // 根据字符集匹配打印方式 #ifdef UNICODE wprintf(L"Error message: %ls\n", lpMsgBuf); #else printf("Error message: %s\n", lpMsgBuf); #endif LocalFree(lpMsgBuf); // 释放FormatMessage分配的内存 }
3. 关键细节说明
- 参数传递正确性:必须传递
(LPTSTR)&lpMsgBuf,确保函数能正确写入分配好的内存地址。 - 格式符匹配:宽字符串用
%ls配合wprintf,窄字符串用%s配合printf,避免输出空内容或乱码。 - 错误处理增强:
FormatMessage失败时直接返回,防止后续访问空指针导致程序崩溃。 - 内存管理:无论格式化是否成功,只要
lpMsgBuf被分配,必须用LocalFree释放,避免内存泄漏。
4. 测试验证
调用失败的WinAPI后执行printLastMessage(),会正确输出错误码和对应系统信息,比如错误码87会输出:
Error code: 87 Error message: 参数错误。
内容的提问来源于stack exchange,提问作者Etienne Poulin
相关产品推荐
相关产品推荐

