在 C++/CLI 包装类中翻译异常的最佳实践

发布于 2024-07-05 12:22:38 字数 160 浏览 5 评论 0原文

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

I am writing a .NET wrapper class for an existing native class which throws exceptions. What are the best practices for translating between native C++ exceptions and Managed exceptions? Catch and re-throw on a one-to-one basis (e.g. std::invalid_argument -> System.System.ArgumentException)? Is there a mapping already drawn up somewhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心碎无痕… 2024-07-12 12:22:38

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

但在我必须执行此操作的上一个项目中,我采用了更简单的方法,最终为逻辑错误和运行时错误编写了几个 System.Exception 派生类。 然后我会捕获这 2 个基类并使用 typeid(err) 写入抛出的 .NET 消息。 这样我就不会“丢失”C++ 抛出的内容,但也不必映射除最重要的之外的所有内容。

There is no standard mapping that I know of. What I've done in the past is translate the ones I know about, and a catch block for System.Runtime.InteropServices.SEHException. All non-translated exceptions will be turned into that exception. As long as you have a debug build of the code that is throwing the exception, you should get a nice stack trace. Then you can go and look at the exception and write the wrapper.

But on the last project I had to do this on, I went with something much more simple, I ended up writing a couple of System.Exception derivatives for logic_error and runtime_error. Then I would catch those 2 base classes and use typeid(err) to write the .NET message that got thrown. This way I didn't "lose" what was being thrown from the C++ but didn't have to map everything except the most important ones.

七禾 2024-07-12 12:22:38

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

此外,还存在非托管代码的 SEH 异常问题。 根据您的情况,可能还需要抓住并包裹它们。

One-to-one mapping seems the sanest approach to me. "Universal" mapping is hardly possible because of application-specific exceptions, although there is some obvious mapping for STL exception classes.

Also there is an issue of SEH exceptions from unmanaged code. Depending on your situation it might be necessary to catch and wrap them too.

述情 2024-07-12 12:22:38

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

I think it depends on the design of the wrapper. If the manager wrapper's interface will be nearly identical to the unmanaged library's interface, then rethrow the exceptions 1:1. If you're changing the interface significantly, then throw exceptions most appropriate for the new interface. Either way, make sure the wrapper throws exceptions any time an operation cannot be completed to be consistent with .NET design guidelines.

盗心人 2024-07-12 12:22:38

你到底想做什么?

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

What are you really trying to do?

Interop already translates native exceptions to managed, including SEH exceptions. However, good design dictates that ALL exceptions should be caught at the native API level. You shouldnt deviate from this unless there is a good reason. We dont know enough about your design.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文