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

时间:2008-10-08 14:55:35

标签: c++ .net exception delegates managed-c++

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

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

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

4 个答案:

答案 0 :(得分:2)

使用

从托管代码中捕获
try
{
  throw gcnew InvalidOperationException();
}
catch(InvalidOperationException^ e)
{
  // Process e
  throw;
}

[assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)];
程序集上的

捕获托管和非托管异常

答案 1 :(得分:1)

甚至不要远程尝试使“非托管”代码意识到它将不得不处理.NET。

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

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

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