如何通过COM公开通过结构化异常处理捕获的异常? 我的COM服务器在Visual C++中使用了大量的C++代码。其他C++代码有时会在 >代码> > >中,除了之外,并将结构化异常转换为自定义C++异常。这部分我不能改变

如何通过COM公开通过结构化异常处理捕获的异常? 我的COM服务器在Visual C++中使用了大量的C++代码。其他C++代码有时会在 >代码> > >中,除了之外,并将结构化异常转换为自定义C++异常。这部分我不能改变,c++,winapi,visual-c++,com,structured-exception,C++,Winapi,Visual C++,Com,Structured Exception,我的COM服务器的任何方法都不应允许这些异常通过COM边界传播,因此它必须捕获这些异常并将其转换为HRESULTs。这些自定义C++异常包含在翻译过程中获得的原始错误代码——它类似于代码>例外。问题是我如何设计一个适当的HRESULT值,以便客户机能够尽可能多地了解发生了什么(并且可能在看到访问冲突后决定重新启动服务器(如果是inproc),以及服务器本身) 假设它是WinBase.h #define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLAT

我的COM服务器的任何方法都不应允许这些异常通过COM边界传播,因此它必须捕获这些异常并将其转换为
HRESULT
s。这些自定义C++异常包含在翻译过程中获得的原始错误代码——它类似于代码>例外。问题是我如何设计一个适当的
HRESULT
值,以便客户机能够尽可能多地了解发生了什么(并且可能在看到访问冲突后决定重新启动服务器(如果是inproc),以及服务器本身)

假设它是
WinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
后者在
WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
我可以使用WIN32()中的
HRESULT\u
将该代码转换为
HRESULT
,假设它首先是一个WIN32错误


我是在这里使用WIN32()中的
HRESULT\u,还是使用任何其他方式进行翻译?

您应该返回
HRESULT
代码,在那里您选择适当的代码来指示操作状态。它不一定是失败代码,但您通常希望显示满足
FAILED(…)
宏的内容,例如
e\u FAIL
,或
DISP\u e\u EXCEPTION
HRESULT\u FROM\u WIN32(ERROR\u UNHANDLED\u EXCEPTION)

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

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

ATL提供包装
SetErrorInfo
API,还建议生成
HRESULT
code:

。。。如果
hRes
为零,则
AtlReportError
的前四个版本返回
DISP_E_EXCEPTION
。最后两个版本返回宏的结果
MAKE\u HRESULT(1,FACILITY\u ITF,nID)


也许在这里,使用
IErrorInfo
基础设施可以派上用场<代码>\u com\u error
包含指向它的指针。在被叫方,我想我记得有类似SetErrorInfo的东西。。。我当时用的是ATL。。。咳嗽是10年前的事吗?@user2225104即使使用
IErrorInfo
我也负责制作
HRESULT
值。0xC0000005已经是一个有效的HRESULT代码,表示失败,没有理由更改它。不要隐藏这么肮脏的东西。@HansPassant我检查了-
HRESULT\u FROM\u WIN32()
0xC0000005
转换为自身。我想这意味着我们可以随处使用它,得到适当的值。@ SypEclipse或者其他方式来解释我的观点:如果你是那个函数的实现者,它调用C++代码不知道如何处理那个结构化异常,那么调用方也不太可能知道。尽管如此,他甚至不知道/不介意使用C++代码来实现。那些直接打电话的人更不在乎。当您向上移动调用树时,您也应该向上移动错误抽象。然后,他们在更高级别上需要的唯一信息是“我的特性/功能失败,原因是COM对象xy。”我认为OP不确定,通过接口传递的
HRESULT
是否应该代表根本原因。也许您可以强调,通常不需要跨接口边界携带特定信息。您的前两段已经说明了这一点,但明确地解释可能会有所帮助。@IInspectable根本原因可能会引起调用方的极大兴趣-如果出现结构化异常,服务器可能会得到toast,客户端最好重新启动服务器(如果是进程内服务器,则重新启动服务器本身).@IInspectable:在这里传递异常并没有不确定性。而是关于使用COM策略可以/应该返回什么标准。但是,COM只负责处理异常并返回HRESULT代码,从而让客户端/服务器定义特定于服务器的代码以指示致命错误。@sharptooth:通常,调用方感兴趣的唯一信息是操作是否成功,如
HRESULT
的MSB所示。调用者对根本原因不感兴趣。但是,这对支持工程师很有帮助。处理此问题的一种方法是在异常处理程序中编写一个小型转储(用于诊断),并将一些故障代码传递回调用方。