澄清混合本机/托管方案中C ++ / CLI中的异常处理

时间:2015-03-18 00:56:01

标签: .net visual-c++ exception-handling c++-cli mixed-mode

我们有一个使用本机库的应用程序,它是用C ++ / CLI编写的。

我们的本机库有自己的C ++异常类ErrorException。

代码的结构是这样的,即应用程序的主循环是本机代码,然后调用(托管)应用程序代码,然后有时会回调到本机库。

使用/ EHsc编译本机库(除了使用/ EHa编译的文件之外,由于catch(...)捕获结构化异常(例如访问冲突)的问题,这对我来说似乎是错误的!)。 / p>

我所做的是我在C ++ / CLI代码中包装(大多数)函数(我相信)可以在MANAGED_TRY_START / MANAGED_TRY_END宏中抛出托管异常,如下所示:

#define MANAGED_TRY_START try {
#define MANAGED_TRY_END \
    } \
    catch(System::Runtime::InteropServices::SEHException^) { \
        throw; \
    } \
    catch(System::Exception^ ex) { \
        ConvertAndThrowSystemException(ex); \
        throw NULL; \
    } \

ConvertAndThrowSystemException是一个函数,它将System :: Exception转换为ErrorException并抛出它。

现在,我的问题是,那就够了吗?我问,因为这个特定的应用程序显示频繁的不稳定性和内存问题,我担心异常是错误的。

在相关的说明中,我们使用dr.memory作为我们的Valgrind替换Windows的本机代码,但它似乎不喜欢.Net。有没有人建议使用类似的工具呢?我们尝试过Deleaker,我们得到了相当奇怪的结果,就像声称堆栈分配的对象被泄露一样。

具体来说,让我们说堆栈看起来像: foo()[native] bar()[managed] foob​​ar()[native] ...

和foo()抛出C ++异常。 foob​​ar()对foo的调用是在try块中,对foo()抛出的类型使用相应的catch()块。 foob​​ar()是用/ Ehsc编译的。

以下哪种情况有foobar()捕获异常,所有干预的C ++堆栈对象都被正确销毁,如果有的话?

  • bar()没有try / catch
  • bar()的内容包含在我的MANAGED_TRY_START / MANAGED_TRY_END

1 个答案:

答案 0 :(得分:3)

/EHa不是问题。使用catch (...)是个问题。

/EHa是两者都有操作系统异常的唯一方法(此类别中包含.NET异常)正确展开C ++堆栈帧,并使C ++异常正确展开.NET堆栈帧。