问题
Consider the following Fortran subroutine, defined in test.f:
subroutine test(py_func)
use iso_fortran_env, only stdout => output_unit
external py_func
integer :: a
integer :: b
a = 12
write(stdout, *) a
b = py_func(a)
write(stdout, *) b
end subroutine
Also the following Python code, defined in call_test.py:
import test
def func(x):
return x * 2
test.test(func)
Compiled with the following (Intel compiler):
python f2py.py -c test.f --fcompiler=intelvem -m test
I expect this as output when I run test:
12
24
But I actually get this:
12
0
It seems as if b
is being initialised with a default value instead of the result of test
. I have tried using the following in the Fortran:
!f2py intent(callback) py_func
external py_func
!f2py integer y,x
!f2py y = py_func(x)
But my program crashes after the printout of 12
to the console.
Any ideas what could be going on here? The reason for the crash would be a bonus, but I'm really just interested in getting a simple callback working at this point.
回答1:
I don't claim to understand it, I found the answer on an F2Py forum thread. Adding integer py_func
(not prefixed by !f2py
) does the trick for me:
subroutine test(py_func)
use iso_fortran_env, only stdout => output_unit
!f2py intent(callback) py_func
external py_func
integer py_func
!f2py integer y,x
!f2py y = py_func(x)
integer :: a
integer :: b
a = 12
write(stdout, *) a
b = py_func(a)
write(stdout, *) b
end subroutine
Perhaps this is to do with space being needed for a temporary value used to store the result before being assigned to b? In any case, it is apparently compiler-dependent, which explains why it is not in various F2Py callback examples you can find elsewhere online.
来源:https://stackoverflow.com/questions/20265697/how-to-return-a-value-from-a-python-callback-in-fortran-using-f2py