在C ++ / CLI包装器类中转换异常的最佳实践

时间:2020-03-06 14:34:06  来源:igfitidea点击:

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

解决方案

据我所知,没有标准的映射。我过去所做的就是翻译我所知道的内容,以及翻译System.Runtime.InteropServices.SEHException的catch块。所有未翻译的异常都将变成该异常。只要我们具有引发异常的代码的调试版本,就应该获得不错的堆栈跟踪。然后,我们可以查看异常并编写包装器。

但是在上一个必须执行的项目上,我做了一些简单得多的工作,最终我为logic_error和runtime_error编写了几个System.Exception派生类。然后,我将捕获这两个基类,并使用typeid(err)编写抛出的.NET消息。这样,我不必"丢掉"从C ++抛出的内容,而不必映射除最重要的内容以外的所有内容。

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

另外,还有一个来自非托管代码的SEH异常问题。根据情况,可能也有必要将它们包裹起来。

我认为这取决于包装纸的设计。如果管理器包装器的接口与非托管库的接口几乎相同,则将异常1:1抛出。如果我们要对界面进行重大更改,则抛出最适合新界面的异常。无论哪种方式,都要确保包装程序在无法完成任何操作的任何时间抛出异常,以符合.NET设计准则。

我们到底想做什么?

Interop已经将本机异常转换为托管(包括SEH异常)。但是,良好的设计要求应在本机API级别捕获所有异常。除非有充分的理由,否则我们不应该偏离这一点。我们对设计不够了解。