在非托管回调委托中抛出异常的含义

本文关键字:抛出异常 回调 | 更新日期: 2023-09-27 18:16:12

在非托管回调期间使用的委托内部抛出异常的含义或不可感知的后果是什么?以下是我的情况:

非托管C:

int return_callback_val(int (*callback)(void))
{
  return callback();
}

管理c#:

[DllImport("MyDll.dll")]
static extern int return_callback_val(IntPtr callback);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int CallbackDelegate();
int Callback()
{
  throw new Exception();
}
void Main()
{
  CallbackDelegate delegate = new CallbackDelegate(Callback);
  IntPtr callback = Marshal.GetFunctionPointerForDelegate(delegate);
  int returnedVal = return_callback_val(callback);
}

在非托管回调委托中抛出异常的含义

本机代码将在未处理的异常上爆炸,程序终止。

如果你真的想处理那个异常,那么你需要在本机代码中使用自定义的__try/__catch关键字。这是非常无用的,托管异常的所有细节都丢失了。唯一的区别特征是异常代码0xe0434f4d。由于您无法确切地知道哪里出了问题,因此也无法可靠地恢复程序状态。最好别抓住它。或者最好别扔。

我认为对COM对象说你有异常的正确方法是简单地返回HRESULT.E_FAIL。

现在不能测试它,但我认为,如果COM对象在另一个进程中,你所要做的就是杀死你的进程和COM对象可能变得无响应,等待你的代码从回调函数返回(因为你的进程已经死了)。