【问题标题】:How to rethrow a C++ exception as a .net exception preserving the message, stack trace and original exception?如何将 C++ 异常重新抛出为 .net 异常,保留消息、堆栈跟踪和原始异常?
【发布时间】:2015-10-08 12:03:57
【问题描述】:

我在 C++/CLI 中有一个“包装器库”,它与非托管的第三方库通信,以使我的 .net 项目中的功能可用。非托管库的某些函数会抛出继承自 std::exception 的异常。我想在 .net 空间中将它们作为有意义的异常重新抛出。 目前,我对每个非托管调用都执行此操作:

try {
    myThirdPartyObject -> doUnmanagedStuff();
} catch(std::exception e) {
    throw gcnew InvalidOperationException(gcnew String(e.what()));
}

但是,这既不会保留调用堆栈,也不会保留原始异常。如果我只是让异常冒泡,我只会将其作为 SEHException 并带有消息“外部组件已引发异常”。

这可能吗?如果可以,是如何做到的?

【问题讨论】:

  • 有点离题,但你应该通过引用来捕获 C++ 异常 (catch (std::exception& e))
  • 确实是为了避免切片。 “const” 参考更好(catch (const std::exception& e))
  • @SébastienCôté:为什么捕获 const 引用更好?您永远不会在 catch 块中遇到 const 异常。并且在重新抛出之前您不能调用任何非常量函数或修改异常。
  • 在原生 C++ 程序中,除了 exception::what() 之外,您不会得到堆栈跟踪或其他任何东西。当你重新抛出它时,它并没有神奇地变得更好。

标签: .net c++-cli


【解决方案1】:

我认为这是不可行的。与托管代码不同,标准 C++由为您处理这些事情的运行时引擎提供支持。有一些方法可以捕获堆栈跟踪,但它们是特定于平台的(参见 Windows 方式here);无论如何,堆栈信息应该被捕获并附加到异常对象之前抛出它,在你的情况下这不是一个选项,因为你正在调用第三方库,我假设你不能修改。

【讨论】:

  • “sentient 运行时引擎”?
  • CLR 的迂腐表达 :)
猜你喜欢
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
相关资源
最近更新 更多