2013-11-28 3 views
2

Рассмотрим следующую Fortran подпрограмму, определенную в test.f:Как вернуть значение из функции обратного вызова Python в Fortran с использованием F2Py

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 

также следующий код Python, определенный в call_test.py:

import test 

def func(x): 
    return x * 2 

test.test(func) 

Составитель со следующим (Intel компилятором):

python f2py.py -c test.f --fcompiler=intelvem -m test 

я ожидаю это как выход, когда я бегу Тест:

 12 
     24 

Но я на самом деле получить это:

 12 
     0 

Кажется, как будто b будет инициализируется со значением по умолчанию вместо результата test. Я попытался с помощью следующих в Fortran:

!f2py intent(callback) py_func 
     external py_func 
!f2py integer y,x 
!f2py y = py_func(x) 

Но моя программа вылетает после распечатки 12 на консоль.

Любые идеи, что здесь может быть? Причиной катастрофы будет бонус, но я действительно заинтересован в том, чтобы получить простой обратный вызов, работающий на этом этапе.

ответ

0

Я не претендую на понимание, я нашел ответ на F2Py forum thread. Добавление integer py_func (не префиксом !f2py) делает трюк для меня:

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 

Возможно, это связано с пространством нужности для временного значения, используемого для хранения результата перед назначением б? В любом случае, это, по-видимому, зависит от компилятора, что объясняет, почему он не находится в разных примерах обратного вызова F2Py, которые вы можете найти в другом месте в Интернете.

+2

У вас нет 'implicit none' в вашем файле, поэтому' py_func' считается 'real' из-за неявных правил ввода. –