phi*_*red 9 .net destructor c++-cli exception raii
我们有大量的本机C++代码,编译成DLL.
然后我们有几个包含C++/CLI代理代码的dll来包装C++接口.
最重要的是,我们有C#代码调用C++/CLI包装器.
标准的东西,到目前为止.
但是我们有很多情况允许将原生C++异常传播到.Net世界,并且我们依赖.Net将这些包装为System.Exception对象的能力,并且在大多数情况下这很好.
但是,我们发现当异常传播时,不会调用throw的范围内对象的析构函数!
经过一些研究,我们发现这是一个众所周知的问题.然而,解决方案/解决方案似乎不太一致.我们确实发现,如果使用/ EHa而不是/ EHsc编译本机代码,问题就会消失(至少在我们的测试用例中).但是我们更喜欢使用/ EHsc,因为我们自己将SEH异常翻译成C++异常,我们宁愿让编译器有更多的优化空间.
是否还有其他解决方法可以解决此问题 - 除了在(本机)try-catch-throw(除C++/CLI层之外)中包含跨本机管理边界的每个调用之外?
不幸的是,我不相信有任何好的解决方法。MS 平台上的 C++ 异常实现是使用 SEH 异常 (IIRC) 来实现的。CLR 挂钩 SEH 处理以捕获本机异常并将其处理为 CLR 异常。由于它在 SEH 级别捕获它们,因此该异常看起来像 C++ 的 SEH 异常,并且析构函数相应地运行或不运行。
正如您所指出的,最好的两个选择是
理想情况下,无论如何你都应该做第二个。根据我的经验,允许 C++ 异常跨越组件边界被认为是不好的做法。
您还可以使用_set_seh_translator(文档)实现一个黑客解决方案。不过,我强烈建议避免使用该函数,因为它可能会无意中破坏 CLR 异常处理并导致许多不必要的问题。