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

时间:2011-11-29 18:13:50

标签: c# .net exception pinvoke

在非托管回调期间使用的委托内部抛出异常有什么影响或未被察觉的后果?这是我的情况:

非托管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);
}

2 个答案:

答案 0 :(得分:7)

本机代码将对未处理的异常进行炸弹,程序终止。

如果您确实想要处理该异常,则需要在本机代码中使用自定义__try/__catch keywords。这是无用的,托管异常的所有细节都将丢失。唯一的区别特征是异常代码0xe0434f4d。由于您无法准确知道出现了什么问题,因此无法可靠地恢复程序状态。最好不要抓住它。或者最好不要抛弃它。

答案 1 :(得分:0)

我认为向COM对象说出异常的正确方法就是返回HRESULT.E_FAIL。

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