5

我用 Visual C++ 实现的 COM 服务器使用了大量其他 C++ 代码。其他 C++ 代码有时会将代码包装在__try-__except并将结构化异常转换为自定义 C++ 异常。这部分我无法改变。

我的 COM 服务器的任何方法都不应该让这些异常通过 COM 边界传播,因此它必须捕获并将它们转换为HRESULTs。那些自定义 C++ 异常包含在翻译过程中获得的原始错误代码 - 它类似于EXCEPTION_ACCESS_VIOLATION. 问题是我如何制作一个适当的HRESULT值,以便客户端尽可能多地了解发生的事情(并且可能在看到访问冲突后决定重新启动服务器(以及在 inproc 的情况下重新启动服务器))。

假设它是EXCEPTION_ACCESS_VIOLATIONWinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION

后者定义在WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)

我可以使用HRESULT_FROM_WIN32()将该代码转换为首先HRESULT假设它是Win32 错误

HRESULT_FROM_WIN32()在这里使用还是使用任何其他方式进行翻译?

4

1 回答 1

4

您应该返回HRESULT代码,您可以在其中选择适当的代码来指示操作状态。它不一定是失败代码,但您通常希望显示满足FAILED(...)宏的内容,例如E_FAIL、 或DISP_E_EXCEPTIONHRESULT_FROM_WIN32(ERROR_UNHANDLED_EXCEPTION)

调用者极不可能与特定的异常相关的进行比较HRESULT,因此特定的故障代码对于诊断更有意义。此外,当您在退出 COM 方法之前完成处理异常时,无需返回特定HRESULT代码,因为不需要或不需要额外的操作。

要提供更多信息,可以使用ISupportErrorInfo,IErrorInfo和朋友。调用者可以自动检索自由文本描述和许多流行的环境,因此例如 .NET 调用者将获得有关异常消息的附加信息,而不是从HRESULT代码生成的标准消息。

ATL 提供AtlReportError包装SetErrorInfoAPI,这也建议生成HRESULT代码:

...如果hRes为零,则AtlReportError返回的前四个版本DISP_E_EXCEPTION。最后两个版本返回宏的结果MAKE_HRESULT( 1, FACILITY_ITF, nID )

于 2015-04-23T11:37:11.730 回答