7

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

/EH混合异常处理模型时还有其他注意事项吗?

4

2 回答 2

5

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

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

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

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

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

于 2011-12-10T00:01:25.173 回答
5

调用没有启用异常代码应该不会产生任何问题——这与调用外部 C 函数或类似的东西没有什么不同。

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

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

于 2011-06-29T19:35:29.680 回答