【问题标题】:How to handle exceptions from native code?如何处理来自本机代码的异常?
【发布时间】:2016-11-07 15:34:58
【问题描述】:

假设我的应用程序由 3 个组件组成。它们是:

  1. c++ 原生库
  2. c++ cli 管理库,封装了原生库
  3. c# gui 应用程序。

据我了解,从本地 c++ 库抛出的任何本地异常都将使用 SEHException 托管类进行包装。我对接下来的步骤感兴趣,建议在创建此类异常对象后做什么。

我是否应该在 c++ cli 托管库中捕获所有此类可能的异常,然后创建适当的托管异常?像这样的:

void some_managed_action()
{
    try
    {
       native_object->some_native_action();
    }
    catch (const NativeException& e)
    {
       // What should I do with exception e and native object? before throwing new managed exception
       // Will SEH wrapper automatically delete native exception object
       // delete all native objects?
       throw gcnew ManagedException(get_message(e));
    }
}

也许这种方法存在一些缺陷?感谢您的任何建议。

【问题讨论】:

  • 没有明显的理由要更改此代码中的任何内容。除了异常类型名称之外,“UnmanagedException”可能更有意义,因为它就是从那里来的。除了错误报告之外,C# 代码不太可能用它做任何合理的事情,您可以提供的细节越多越好。
  • @Hans Passant,据我了解,通过原生对象捕获异常比通过 appprop 更可取。包裹托管一个? docs 说:如果一个非托管类型被 catch(Object^) 捕获,它不会破坏抛出的对象。
  • 当您在 sn-p 中编写“NativeException”时,每个人都会认为这是一个原生 C++ 类型。这不仅很好,而且需要从异常对象中获取任何信息。在没有任何相关信息的情况下传递异常是一个非常非常糟糕的主意。它仍然可以工作,但你的 C# 代码当然只能终止程序。所以原生异常对象是否泄露根本不重要。

标签: c# exception-handling c++-cli


【解决方案1】:

使用

try 
{
} 
catch (Exception ex) 
{
    // .NET exception
} 
catch 
{
    // native exception
}

处理异常的 catch 块捕获所有公共语言 符合规范 (CLS) 的异常。然而,它并没有抓住 不符合 CLS 的异常。不符合 CLS 的异常可以是 从本机代码或由 Microsoft 中间语言 (MSIL) 汇编程序。请注意,C# 和 Visual Basic 编译器不允许不符合 CLS 的异常 被抛出并且 Visual Basic 不捕获不符合 CLS 的 例外。如果 catch 块的目的是处理所有 异常,请使用以下通用 catch 块语法。

C#:捕捉 {}

CA2102: Catch non-CLSCompliant exceptions in general handlers

【讨论】:

  • 值得一提的是,我不知道托管 c++ 引发的异常应该由 RuntimeWrappedException(而不是 SEHException)包装。
  • 这没有多大意义,本机代码永远不会抛出托管异常。天堂禁止它永远确实发生。幸运的是,CLR 很可能会将其视为 CSE(损坏状态异常),因此它永远不会捕获。
  • @HansPassant 我不知道您的评论是否是写给我的,但从您的内容来看,我认为这是对操作的假设。操作员可能阅读了这篇文章:msdn.microsoft.com/en-us/library/ms404228.aspx,因此他提到了 RuntimeWrappedException
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
相关资源
最近更新 更多