You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:01:23