在C ++绑定中捕获fortran运行时错误和信号

时间:2019-06-09 20:50:30

标签: c++ fortran language-binding

我希望能够在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':没有此类文件或目录

我希望能够使用信号捕获此错误和其他运行时错误。

2 个答案:

答案 0 :(得分:2)

这至少对于GFortran无效。当OPEN语句失败时,GFortran运行时库将自行关闭,直到最后才生成信号。因此,当您可以在信号处理程序中捕获信号时,libgfortran已经关闭了自身(包括关闭所有打开的文件)。

正如弗拉基米尔F(Vladimir F)在评论中说的那样,解决方案是使用OPEN说明符捕获iostat=语句中的错误。

答案 1 :(得分:0)

我已经实现了类似的功能,以便对来自C / C ++的Fortran代码的C绑定进行单元测试,以使用abortsetjmp捕获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代码在setjmplongjmp之间。

另一方面,有些编译器供应商明确提供了setjmp / longjmp包装器(例如an answer in the already linked question)以及一些具有类似重点的项目:

话虽这么说,但正如其他人已经评论过的那样,只要有可能,使用iostat属性使用适当的错误处理可能是一种更好的(更便于移植的)方法。