在Visual Studio 2010中混合exception处理模型有什么后果?

我有第三方静态库build立与Enable C++ Exceptions设置为/EH标志未指定)。 从启用了C ++exception( /EHa )的代码中调用它会产生什么后果? 如果从库中抛出结构化exception,主应用程序提供给_set_se_translator的函数是否可靠地调用? (我的实验表明它会,但只是想知道这是否是定义的行为)。

混合/EHexception处理模型时是否还有其他注意事项?

调用没有启用异常的代码不会产生任何问题 – 这与调用外部C函数或其他类型的内容没有区别。

调用没有启用异常的代码(启用异常的代码)可能不会在异常禁用代码中包含正确的堆栈展开语义,这意味着您将破坏该代码的不变量,除非它是专门设计用于处理例外。 (例如,某些库(例如ANTLR)分配块中的所有内存,并让用户代码一次释放所有内容,即使不使用异常,也可以使用异常而不会泄漏)。

Raymond Chen有一篇关于C ++的异常处理如何在MSVC ++上工作的内容。 长话短说,它建立在Windows'SEH之上。 因此,它的行为应该类似于在例如C代码中抛出SEH异常的情况。 (不过,我自己并没有证实这一点)

根据MSDN,然后允许混合/ EHa和/ EHsc :

两种异步处理模式(同步和异步)完全兼容,可以在同一应用程序中混合使用。

但是这个规则似乎有一个例外,那就是当从非托管(/ EHsc)传递到托管(/ clr)时 。 托管代码使用结构化异常处理(SEH)捕获所有异常,并且这样会导致在解除堆栈时不调用非托管析构函数 。 有不同的解决方法:

  1. 将非托管代码更改为使用/ EHa而不是/ EHsc。 这有一个缺点,抓住(…)内的非托管代码突然将捕获访问冲突和其他疯狂的东西。
  2. 在非托管代码中创建try-catch块,并确保在非托管世界和托管世界之间不传递任何异常。

    2.1。 可能的中间道路是确保在从非托管的世界向受管理的世界传递异常时期望不会调用析构函数。 在非托管代码中创建一个try-catch包装器,然后在catch-block中将异常重新引发到托管的世界中。