我们有一个使用本机库的应用程序,它是用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] foobar()[native] ...
和foo()抛出C ++异常。 foobar()对foo的调用是在try块中,对foo()抛出的类型使用相应的catch()块。 foobar()是用/ Ehsc编译的。
以下哪种情况有foobar()捕获异常,所有干预的C ++堆栈对象都被正确销毁,如果有的话?
MANAGED_TRY_START
/ MANAGED_TRY_END
宏答案 0 :(得分:3)
/EHa
不是问题。使用catch (...)
是个问题。
/EHa
是两者都有操作系统异常的唯一方法(此类别中包含.NET异常)正确展开C ++堆栈帧,并使C ++异常正确展开.NET堆栈帧。