ABI是否还存在比HRESULT更多的错误信息?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ABI是否还存在比HRESULT更多的错误信息?相关的知识,希望对你有一定的参考价值。

在将常规C ++类移植到Windows运行时类时,我遇到了相当重要的障碍。我的C ++类通过抛出自定义错误对象来报告某些错误情况。这允许客户端方便地过滤公共接口中记录的异常。

我似乎找不到一种可靠的方法来通过ABI传递足够的信息来使用Windows运行时复制相同的fidelity1。假设HRESULT是唯一的广义错误报告信息,我已经评估了以下选项:

  1. '明显'的选择:将异常条件映射到任何预定义的HRESULT values。虽然这在技术上有效(大概),但是在呼叫站点处无法区分源自实现的错误和源自实现的被调用者的错误。
  2. 发明自定义HRESULTs。如果this layout仍然适用于Windows运行时,我可以很容易地设置客户位,并对我的27位错误代码表示感到疯狂。这是有效的,直到其他人也这样做。我不知道有任何方法将HRESULT归因于接口,这将解决这种模糊性。
  3. 即使上述任何一种都可以按预期工作,按照规定投掷hresult_errors,呼叫站点仍然受语言投射的支配。虽然C#似乎允许在ABI中传递任何System.Exception(-derived)错误对象,并在调用站点重新抛出它们,但C ++ / WinRT仅支持14种不同的异常类型(请参阅throw_hresult)。

由于这些选项都没有允许足够完整的错误信息来跨越ABI,因此似乎HRESULT可能还不够。 Windows运行时是否有任何配置允许其他(任意)错误信息通过ABI?


1我并不十分关心传递实际的C ++异常。相反,我正在寻找一种方法,允许客户以自然的方式唯一地识别记录的错误条件。传递自定义Windows运行时错误类型会没问题。

答案

这里有一些选择。我们针对具有明确定义的预期故障模式的Windows运行时API的一般API指南是故障信息应该是正常参数和返回值的一部分。我们通常会在这种情况下创建一个TryDoSomething API,并通过return或out参数提供扩展的错误信息。这对我们来说效果最好,因为没有一致的方法来映射所有语言的异常。这是一个我们希望将来在xlang中重温的话题。

HRESULT可用于警告。除了C ++之外,HRESULT值可能是一个令人讨厌的东西,你需要在本地重新定义它们,因为你不能只使用标题。它们将在大多数语言中生成异常,因此如果这很常见,您将为组件的客户端创建调试器噪声。

最后一个选项允许您跨越ABI边界(以及COM逻辑堆栈,包括跨编组调用)传输存储在COM对象中的特定于语言的异常。实际上,只有使用与组件本身相同的编译器,设置和类型定义编译的C ++代码才能使用它。例如。将它从使用VC编译的组件传递到使用Clang编译的组件可能会导致内存损坏。

假设我没有吓到你,你会想看看RoOriginateLanguageException。它允许您将异常包装在COM对象中,并将其与TLS中的其他winrt错误数据一起存储。我们在投影中使用它来使回调中抛出的异常能够以受控方式使用相同的投影传播到外部代码,该控制方式可以通过使用其他语言或工具编写的其他代码安全地展开。这就是如何实现C#和其他语言的支持。

谢谢,

Ben

以上是关于ABI是否还存在比HRESULT更多的错误信息?的主要内容,如果未能解决你的问题,请参考以下文章

急 | Linux再曝安全漏洞Bash 比心血还严重

DISM 抛出 HRESULT=80310000 错误

如何更正 hresult error.ms sql server

WebBrowser 对 COM 组件的调用返回了错误 HRESULT E_FAIL。

参数错误。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))

参数错误。 (异常来自 HRESULT:0x80070057 (E_INVALIDARG))