c++ - 从 C++ 处理程序捕获时如何获取 Ada 异常消息?

标签 c++ exception g++ ada gnat

使用 GNAT Ada 和 Gnu C++,我将一段 Ada 代码与一个 C++ 包装器连接起来,我想在运行这段(愚蠢的)代码时正确地捕获 Ada 异常:

with ada.text_io;

package body ada_throw is

   procedure ada_throw is
   begin
      ada.text_io.put_line ("hello");
      raise program_error;
   end ada_throw;       

end ada_throw;

相关规范代码为:

package ada_throw is

   procedure ada_throw;
   pragma export (convention => C, entity => ada_throw, external_name => "ada_throw");

end ada_throw;

在 C++ 端执行此操作:

#include <iostream>

extern "C"
{
  void ada_throw();
  void adainit();
}

int main()
{
  adainit();
  ada_throw();
  std::cout << "end of program" << std::endl;
  return 0;
}

我明白了:

hello

raised PROGRAM_ERROR : ada_throw.adb:8 explicit raise

所以异常机制起作用了,我没有得到我的 C++ 程序的最后打印结果并且返回代码不为零。

现在我想捕获异常。如果我使用 catch(...) 它可以工作,但我无法再得到明确的错误消息,所以我尝试了这个:

#include <iostream>
#include <cxxabi.h>
extern "C"
{
  void ada_throw();
  void adainit();
}

int main()
{
  adainit();

  try
  {
    ada_throw();
  }
  catch (abi::__foreign_exception const &e)
  {
    std::cout << "exception" << std::endl;        
  }

  std::cout << "end of program" << std::endl;
  return 0;
}

它工作正常,我得到:

hello
exception
end of program

唯一的问题是 abi::__foreign_exception 没有 what() 方法,所以我无法获得有意义的错误消息。

调试程序以尝试侵入 e 也是一个死胡同,因为它只是一个具有正确类型的空指针:

(gdb) p &e
$2 = (const __cxxabiv1::__foreign_exception *) 0x0

有没有办法从 C++ 中获取它?

最佳答案

在 Ada 中,您可以使用函数 Ada.Exceptions.Exception_NameAda.Exceptions.Exception_Message 获取有关异常发生的信息,它们是标准库的一部分.一种选择是为这两个函数提供一个瘦绑定(bind),并在您需要有关异常的信息时调用它们。 (具体如何将 abi::__foreign_exception 映射到 Ada.Exceptions.Exception_ID 留给读者作为练习。)

另一种选择是让 Ada 编译器明确知道您在另一端编写 C++,并使用 CPlusPlus 而不是 C 作为您的导出约定。这可能会使编译器提供 C++ 理解的异常。

这只是部分答案,因为我很少使用 C++,但我希望它能帮助您朝着正确的方向前进。

关于c++ - 从 C++ 处理程序捕获时如何获取 Ada 异常消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50448406/

相关文章:

c++ - 为什么我们需要分开编译和链接?

Java编译器错误

exception - Symfony2 - 操纵来自内核异常监听器的请求/响应

c++ - 未记录的 GCC 扩展 : VLA in struct

c++ - 试图了解如何选择重载函数

c++ - gdb 中的算术异常,但我没有除以零?

c++ - 模板类内部模板类的外部类运算符

c++ - 想要在 C++ 中创建一个存储 Nx3 值的 2D 指针

c - 在 C 中是否有调用堆栈转储的函数?

c++ - GCC 4.7/4.8 作为 Xcode 的 C/C++ 编译器