4

我正在为抛出异常的现有本机类编写一个 .NET 包装类。在原生 C++ 异常和托管异常之间进行转换的最佳实践是什么?在一对一的基础上捕获并重新抛出(例如 std::invalid_argument -> System.System.ArgumentException)?是否已经在某处绘制了地图?

4

4 回答 4

4

我所知道的没有标准映射。我过去所做的是翻译我所知道的,以及 System.Runtime.InteropServices.SEHException 的 catch 块。所有未翻译的异常都将转换为该异常。只要你有一个抛出异常的代码的调试版本,你就应该得到一个很好的堆栈跟踪。然后你可以去查看异常并编写包装器。

但是在最后一个项目中我必须这样做,我使用了一些更简单的东西,我最终为 logic_error 和 runtime_error 编写了几个 System.Exception 派生类。然后我会捕获这两个基类并使用 typeid(err) 来编写抛出的 .NET 消息。这样我就不会“丢失”从 C++ 抛出的内容,但不必映射除最重要的部分之外的所有内容。

于 2008-09-22T22:32:34.703 回答
2

一对一的映射对我来说似乎是最明智的方法。由于特定于应用程序的异常,“通用”映射几乎是不可能的,尽管 STL 异常类有一些明显的映射。

还有一个来自非托管代码的 SEH 异常问题。根据您的情况,可能还需要捕获和包装它们。

于 2008-09-22T22:34:22.483 回答
2

我认为这取决于包装器的设计。如果管理器包装器的接口与非托管库的接口几乎相同,则以 1:1 重新抛出异常。如果您要显着更改接口,则抛出最适合新接口的异常。无论哪种方式,请确保包装器在任何操作无法完成时抛出异常以符合 .NET 设计准则。

于 2008-09-22T22:43:10.870 回答
1

你真正想做什么?

Interop 已经将本机异常转换为托管异常,包括 SEH 异常。然而,好的设计要求所有的异常都应该在原生 API 级别被捕获。除非有充分的理由,否则您不应该偏离这一点。我们对您的设计知之甚少。

于 2008-09-30T22:30:15.223 回答