在共享库中设置NaN陷阱

时间:2016-12-17 15:55:43

标签: python fortran ctypes gfortran

当我使用ctypes和共享库时,我对NaN陷阱有一点问题。该库是用Fortran编写的,由子程序“除以零”组成:

nantest.f90

subroutine nantest
    real :: a, b, c
    a = 0.
    b = 0.
    c = a/b
    print *, c,a,b
end subroutine nantest

program main
    call nantest
end program main

我使用以下选项从中创建了一个共享库:

gfortran -o nantest.os -c -g -fbacktrace -ffpe-trap=invalid,zero,overflow -fPIC nantest.f90
gfortran -o libnantest.so -shared nantest.os

然后我直接从Python脚本加载这个库:

from ctypes import *
lib = CDLL('./libnantest.so')
lib.nantest_()

它给了我输出,没有任何例外:

          NaN   0.00000000       0.00000000   

有什么问题?它是ctypes还是编译器选项问题? 顺便说一句,当我执行使用相同编译器选项构建的'nantest'程序的直接执行时,我得到了我想要的东西:

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.
Backtrace for this error:
#0  0x7F4D08B6FE08
#1  0x7F4D08B6EF90
#2  0x7F4D087C04AF
#3  0x40080D in nantest_ at nantest.f90:7
#4  0x4008B9 in MAIN__ at nantest.f90:14
Floating point exception

那么,我如何在共享库案例中获取NaN异常? 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

Python运行时设置自己的FPE模式。您可以尝试使用Fortran 2003过程在您需要的确切位置设置FPE异常。它们位于内在模块function getData(fileName, type) { return new Promise(function(resolve, reject){ fs.readFile(fileName, type, (err, data) => { err ? reject(err) : resolve(data); }); }); } 中,例如过程IEEE_EXCEPTIONS。另请参阅GFortran equivalent of ieee_exceptions

ieee_get_halting_mode()仅在编译Fortran程序时有用。

或者使用Python功能(https://docs.python.org/2/library/fpectl.html)来确定是否有任何浮点异常发出信号,但我不知道Python和库之间的接口是否保留它们。