我希望能够在C ++绑定中捕获终止的Fortran运行时错误。 我有一个旧的F90代码可以绑定并期望发生各种错误,例如数值,IO等。
我设法根据以下条件处理STOP: Intercepting Fortran STOP from C++ 并能够在C ++代码中针对这种情况抛出/捕获异常。
我对“ Fortran中的信号处理”有一些了解 https://www.sharcnet.ca/help/images/4/42/Fortran_Signal_Handling.pdf
但是我无法解决这个问题,对于f90 fortran的示例将非常有帮助。
例如,尝试在fortran子例程中打开不存在的文件将给出运行时错误,并且C ++代码终止:
打开(unit = 13,FILE =“ fnameBAD”,status =“ old”,action =“ read”,position =“ rewind”)
Fortran运行时错误:无法打开文件'fnameBAD':没有此类文件或目录
我希望能够使用信号捕获此错误和其他运行时错误。
答案 0 :(得分:2)
这至少对于GFortran无效。当OPEN
语句失败时,GFortran运行时库将自行关闭,直到最后才生成信号。因此,当您可以在信号处理程序中捕获信号时,libgfortran已经关闭了自身(包括关闭所有打开的文件)。
正如弗拉基米尔F(Vladimir F)在评论中说的那样,解决方案是使用OPEN
说明符捕获iostat=
语句中的错误。
答案 1 :(得分:0)
我已经实现了类似的功能,以便对来自C / C ++的Fortran代码的C绑定进行单元测试,以使用abort
和setjmp
捕获longjmp
调用(基本上与{{ 3}}):
#include <setjmp.h>
#include <signal.h>
jmp_buf jmp_env;
void on_sigabrt(int signum)
{
(void) signum; // silence "unused parameter" warning
longjmp(jmp_env, 1);
}
void func()
{
if (setjmp(jmp_env) == 0) {
signal(SIGABRT, &on_sigabrt);
/* YOUR CALLS HERE */
} else {
/* ERROR HANDLING GOES HERE */
}
}
已经描述过的问题@janneb仍然存在:即使longjmp
应该将堆栈恢复到setjmp
的位置,也不能保证恢复Fortran运行时库中的所有内部状态。 / p>
实际上,两本书现代Fortran:样式和用法(规则182)和 Fortran 2003手册(15.6.4)都提到不应包装Fortran代码在setjmp
和longjmp
之间。
另一方面,有些编译器供应商明确提供了setjmp
/ longjmp
包装器(例如an answer in the already linked question)以及一些具有类似重点的项目:
话虽这么说,但正如其他人已经评论过的那样,只要有可能,使用iostat
属性使用适当的错误处理可能是一种更好的(更便于移植的)方法。