在将常规 C++ 类移植到 Windows 运行时类时,我遇到了相当大的障碍。我的 C++ 类通过抛出自定义错误对象来报告某些错误情况。这允许客户端方便地过滤异常,记录在公共(public)界面中。
我似乎找不到一种可靠的方法来通过 ABI 传递足够的信息来使用 Windows 运行时复制相同的保真度1。假设 HRESULT
是唯一的通用错误报告信息,我评估了以下选项:
HRESULT
s。如果 this layout 仍然适用于 Windows 运行时,我可以轻松地设置客户位,然后用我的 27 位错误代码表示来发疯。这有效,直到其他人也这样做。我不知道有任何方法可以将 HRESULT
归因于接口(interface),这可以解决这种歧义。 System.Exception
(派生)错误对象,并在调用站点重新抛出它们,但 C++/WinRT 仅支持大约 14 种不同的异常类型(请参阅 throw_hresult)。 由于这些选项都不允许通过 ABI 获得足够完整的错误信息,因此
HRESULT
似乎根本不够。 Windows 运行时是否有任何设置允许附加(任意)错误信息通过 ABI?1 我对传递实际的 C++ 异常并不十分感兴趣。相反,我正在寻找一种方法,允许客户端以自然的方式唯一地 识别记录的错误条件。传递自定义 Windows 运行时错误类型会很好。
最佳答案
这里有几个选项。对于具有明确定义的预期故障模式的 Windows 运行时 API,我们的一般 API 指南是故障信息应该是正常参数和返回值的一部分。在这种情况下,我们通常会创建一个 TryDoSomething API,并通过 return 或 out 参数提供扩展的错误信息。这对我们来说最有效,因为没有一致的方法来映射所有语言的异常。这是我们希望在 xlang 中重新讨论的话题。在将来。
HRESULT 有一个警告可以使用。 HRESULT 值在除 C++ 之外的任何东西中都可能令人讨厌,因为您不能只使用 header ,因此您需要在本地重新定义它们。它们会在大多数语言中生成异常,因此如果这很常见,您将为组件的客户端创建调试器噪音。
最后一个选项允许您跨 ABI 边界(以及向上 COM 逻辑堆栈,包括跨编码调用)传输存储在 COM 对象中的特定于语言的异常。实际上,它只能被使用与组件本身相同的编译器、设置和类型定义编译的 C++ 代码使用。例如。将它从使用 VC 编译的组件传递到使用 Clang 编译的组件可能会导致内存损坏。
假设我没有吓跑你,你会想看看 RoOriginateLanguageException .它允许您将异常包装在 COM 对象中,并将其与其他 winrt 错误数据一起存储在 TLS 中。我们在投影中使用它来使回调中抛出的异常能够以受控方式传播到使用相同投影的外部代码,该方式可以安全地通过可能使用其他语言或工具编写的其他代码展开。这就是对 C# 和其他语言的支持的实现方式。
谢谢,
本
关于error-handling - ABI 是否保留比 HRESULT 更多的错误信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55850558/