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

如何在C/C++中实现与Marshal.GetExceptionForHR(hr).Message相同的HRESULT转字符串功能?

在C/C++中获取.NET HRESULT的具体错误信息(替代Marshal.GetExceptionForHR)

当使用_com_error处理0x80131500(即COR_E_EXCEPTION)这类.NET相关HRESULT时,只能得到“Unknown error 0x80131500”的模糊提示。以下两种方法可以实现与C#中Marshal.GetExceptionForHR(hr).Message相同的效果,获取具体错误信息:

方法一:通过FormatMessage加载CLR模块获取错误信息

此方法无需额外链接库,兼容性较好:

#include <windows.h>
#include <iostream>
#include <string>

std::wstring GetClrErrorMessage(HRESULT hr)
{
    wchar_t* msgBuffer = nullptr;
    // 加载CLR核心模块,优先clr.dll,兼容旧系统用mscoree.dll
    HMODULE hClrModule = LoadLibraryW(L"clr.dll");
    if (!hClrModule)
    {
        hClrModule = LoadLibraryW(L"mscoree.dll");
    }

    DWORD result = FormatMessageW(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
        hClrModule,
        hr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        reinterpret_cast<LPWSTR>(&msgBuffer),
        0,
        nullptr
    );

    std::wstring errorMsg;
    if (result && msgBuffer)
    {
        errorMsg = msgBuffer;
        LocalFree(msgBuffer);
    }
    else
    {
        // fallback到通用错误格式
        wchar_t hrBuffer[32];
        swprintf_s(hrBuffer, L"Unknown error 0x%08X", hr);
        errorMsg = hrBuffer;
    }

    if (hClrModule)
    {
        FreeLibrary(hClrModule);
    }

    return errorMsg;
}

// 示例调用
int main()
{
    HRESULT hr = 0x80131500; // COR_E_EXCEPTION
    std::wstring msg = GetClrErrorMessage(hr);
    std::wcout << L"错误信息: " << msg << std::endl;
    return 0;
}

方法二:调用CLR原生API GetExceptionForHR

此方法逻辑与C#的Marshal.GetExceptionForHR一致,需要链接mscoree.lib:

#include <windows.h>
#include <mscoree.h>
#include <iostream>
#include <string>
#include <wrl/client.h>

using namespace Microsoft::WRL;

std::wstring GetClrErrorMessageViaCom(HRESULT hr)
{
    ComPtr<IErrorInfo> pErrorInfo;
    HRESULT hrResult = GetExceptionForHR(hr, nullptr, &pErrorInfo);
    if (FAILED(hrResult) || !pErrorInfo)
    {
        wchar_t hrBuffer[32];
        swprintf_s(hrBuffer, L"Unknown error 0x%08X", hr);
        return hrBuffer;
    }

    BSTR bstrMsg = nullptr;
    hrResult = pErrorInfo->GetDescription(&bstrMsg);
    if (FAILED(hrResult) || !bstrMsg)
    {
        wchar_t hrBuffer[32];
        swprintf_s(hrBuffer, L"Unknown error 0x%08X", hr);
        return hrBuffer;
    }

    std::wstring errorMsg(bstrMsg);
    SysFreeString(bstrMsg);
    return errorMsg;
}

// 示例调用
int main()
{
    HRESULT hr = 0x80131500; // COR_E_EXCEPTION
    std::wstring msg = GetClrErrorMessageViaCom(hr);
    std::wcout << L"错误信息: " << msg << std::endl;
    return 0;
}

注意事项

  • 方法一无需额外依赖,适合大多数场景;
  • 方法二需确保项目链接mscoree.lib,且目标系统已安装.NET框架;
  • 两种方法均能正确解析0x8013开头的.NET HRESULT,返回具体错误描述而非“Unknown error”。

内容的提问来源于stack exchange,提问作者manuell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:15:32