如何在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
相关产品推荐
相关产品推荐

