使用GNAT Ada和Gnu C++,我正在将一个Ada代码片段与一个C++ wrapper进行接口处理,并且希望在运行此(愚蠢的)代码时正确地捕获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++中获得它?
function Get_Exception_Machine_Occurrence (X : Exception_Occurrence) return System.Address; pragma Export (Ada, Get_Exception_Machine_Occurrence,"__gnat_get_exception_machine_occurrence"); -- 获取与异常实例对应的机器实例。如果没有机器实例(在不使用GCC机制的运行时中)或者已经丢失(Save_Occurrence不保存机器实例),则为Null_Address。
- LoneWandererGNAT.Last_Exception
(不记得确切的内容)来获取最后抛出的异常。在多线程环境下不完美,但大多数情况下都可以使用(不幸的是,该功能已经损坏,并且正在修复中,仅适用于GNATPro版的beta版本,因此直到2019年才可供公众/ GPL使用)。 - Jean-François Fabre