当我使用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异常? 有什么建议吗?
答案 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和库之间的接口是否保留它们。