使用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例外?
有什么建议吗?
最佳答案
Python运行时设置其自己的FPE模式。您可以尝试使用Fortran 2003过程在所需的确切位置设置FPE例外。它们位于内部模块IEEE_EXCEPTIONS
中,例如过程ieee_get_halting_mode()
。另见GFortran equivalent of ieee_exceptions-ffpe-trap=invalid,zero,overflow
仅在编译Fortran程序时有用。
或使用Python功能(https://docs.python.org/2/library/fpectl.html)来确定是否有任何浮点异常正在发出信号,但是我不知道Python和库之间的接口是否保留了它们。
关于python - 在共享库中设置NaN陷阱,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41200386/