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

时间:2022-09-01 11:23:21

I have unmanaged C++ calling a managed delegate via the function pointer provided by Marshal::GetFunctionPointerForDelegate. This delegate has the potential to throw an exception. I need to be able to properly handle this exception in my unmanaged C++ to ensure things like pointer cleanup, and potentially rethrow the exception up into more managed code. The call stack is similar to this:

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

Managed Code -> Unmanaged C++ -> callback to Managed Code via delegate (exception can be thrown here).

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

Anyone have pointers for properly handling this situation so that the resources in unmanaged code can be cleaned up and a usable exception can be thrown out to the managed code which initiated the whole call stack?

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

5 个解决方案

#1


2  

Catching from managed code with

从托管代码中获取

try
{
  throw gcnew InvalidOperationException();
}
catch(InvalidOperationException^ e)
{
  // Process e
  throw;
}

And an

[assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)];

on your assembly catches managed and unmanaged exceptions

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

#2


1  

Don't even remotely try to make the "unmanaged" code aware of the fact that it will have to deal with .NET.

甚至不要远程尝试使“非托管”代码意识到它必须处理.NET这一事实。

Return a non-zero value from your callback to signal the presence of an error. Provide a (thread local) global string object describing the error so that you can retrieve a helpful error message for the user.

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

This may involve wrapping your delegate into another function under the scenes, which will catch all the exceptions and return the error code.

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

#3


0  

One approach would be to use SEH, and do the cleanup in the exception filter before continuing the exception propagation. But I'm not sure that is overly legal since you would be doing a lot of work in the filter. You also wouldn't know anything about the managed exception being propagated.

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

An alternative is to wrap the managed delegate with your own managed function that catches the exception and in turn throws an unmanaged exception ... which you can then catch in your unmanaged code.

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

When the unmanaged code has done its cleanup use another helper managed function to re-throw the original managed exception

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

#4


0  

Managed code represents exceptions as hardware exceptions, unlike C++. You could use SEH. Remember that you always get the chance to run the exception filter.

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

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

#5


-1  

I was told...{the vector can't show if variables a&b weren't declared in the scope process. After a bit of digging figured out that the loop hole was as follows--- weibull_distribution> unmanaged_code

我被告知...... {向量无法显示变量a和b是否未在范围过程中声明。经过一番挖掘后发现循环孔如下--- weibull_distribution> unmanaged_code

#1


2  

Catching from managed code with

从托管代码中获取

try
{
  throw gcnew InvalidOperationException();
}
catch(InvalidOperationException^ e)
{
  // Process e
  throw;
}

And an

[assembly:RuntimeCompatibility(WrapNonExceptionThrows = true)];

on your assembly catches managed and unmanaged exceptions

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

#2


1  

Don't even remotely try to make the "unmanaged" code aware of the fact that it will have to deal with .NET.

甚至不要远程尝试使“非托管”代码意识到它必须处理.NET这一事实。

Return a non-zero value from your callback to signal the presence of an error. Provide a (thread local) global string object describing the error so that you can retrieve a helpful error message for the user.

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

This may involve wrapping your delegate into another function under the scenes, which will catch all the exceptions and return the error code.

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

#3


0  

One approach would be to use SEH, and do the cleanup in the exception filter before continuing the exception propagation. But I'm not sure that is overly legal since you would be doing a lot of work in the filter. You also wouldn't know anything about the managed exception being propagated.

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

An alternative is to wrap the managed delegate with your own managed function that catches the exception and in turn throws an unmanaged exception ... which you can then catch in your unmanaged code.

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

When the unmanaged code has done its cleanup use another helper managed function to re-throw the original managed exception

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

#4


0  

Managed code represents exceptions as hardware exceptions, unlike C++. You could use SEH. Remember that you always get the chance to run the exception filter.

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

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

#5


-1  

I was told...{the vector can't show if variables a&b weren't declared in the scope process. After a bit of digging figured out that the loop hole was as follows--- weibull_distribution> unmanaged_code

我被告知...... {向量无法显示变量a和b是否未在范围过程中声明。经过一番挖掘后发现循环孔如下--- weibull_distribution> unmanaged_code