如何在非托管 C++ 中捕获托管异常(来自委托)?

Posted

技术标签:

【中文标题】如何在非托管 C++ 中捕获托管异常(来自委托)?【英文标题】:How do you catch a managed exception (from a delegate) in unmanaged C++? 【发布时间】:2008-10-08 14:55:34 【问题描述】:

我有非托管 C++ 通过 Marshal::GetFunctionPointerForDelegate 提供的函数指针调用托管委托。该委托有可能引发异常。我需要能够在我的非托管 C++ 中正确处理此异常,以确保诸如指针清理之类的事情,并可能将异常重新抛出到更多托管代码中。调用栈类似这样:

托管代码 -> 非托管 C++ -> 通过委托回调托管代码(此处可以抛出异常)。

任何人都有正确处理这种情况的指针,以便可以清理非托管代码中的资源并将可用异常抛出到启动整个调用堆栈的托管代码?

【问题讨论】:

【参考方案1】:

从托管代码中捕获

try

  throw gcnew InvalidOperationException();

catch(InvalidOperationException^ e)

  // Process e
  throw;

还有一个

[assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)];

在您的程序集中捕获托管和非托管异常

【讨论】:

【参考方案2】:

甚至不要远程尝试让“非托管”代码意识到它必须与 .NET 打交道这一事实。

从您的回调中返回一个非零值以表示存在错误。提供一个描述错误的(线程本地)全局字符串对象,以便您可以为用户检索有用的错误消息。

这可能涉及将您的委托包装到场景下的另一个函数中,该函数将捕获所有异常并返回错误代码。

【讨论】:

【参考方案3】:

一种方法是使用 SEH,并在继续传播异常之前在异常过滤器中进行清理。但我不确定这是否过度合法,因为您将在过滤器中做很多工作。您也不会知道有关正在传播的托管异常的任何信息。

另一种方法是使用您自己的托管函数来包装托管委托,该函数捕获异常,然后引发非托管异常......然后您可以在非托管代码中捕获该异常。

当非托管代码完成清理后,使用另一个辅助托管函数重新抛出原始托管异常

【讨论】:

【参考方案4】:

托管代码将异常表示为硬件异常,这与 C++ 不同。你可以使用 SEH。请记住,您总是有机会运行异常过滤器。

http://msdn.microsoft.com/en-us/library/ms680657(v=VS.85).aspx

【讨论】:

【参考方案5】:

有人告诉我...如果变量 a&b 未在作用域进程中声明,则向量无法显示。经过一番挖掘发现循环漏洞如下--- weibull_distribution> unmanaged_code

【讨论】:

以上是关于如何在非托管 C++ 中捕获托管异常(来自委托)?的主要内容,如果未能解决你的问题,请参考以下文章

C#:捕获混合托管/非托管进程的所有错误/异常

在非托管 C++ 程序中实现 C# DLL COM 文件

如何在托管 c++ 2010 中向事件添加委托?

在 C# 中传递 IntPtr 指针后,在非托管 C++ 代码中分配数组,编组类型

使用来自 C# 的托管 C++ dll

我想从 C++ 非托管代码调用 C# 委托。无参数委托工作正常,但有参数委托使我的程序崩溃