考虑这个 C 互操作的 Fortran 子例程,它从 Python 调用并将 Python 回调函数作为输入参数,然后调用它,
module FortranFunc_mod
! C-interoperable interface for the python callback
abstract interface
function getSquare_proc( x ) result(xSquared) bind(C)
use, intrinsic :: iso_c_binding, only: c_double
real(c_double), intent(in) :: x
real(c_double) :: xSquared
end function getSquare_proc
end interface
contains
subroutine fortranFunc( getSquareFromPython ) bind(C, name="fortranFunc")
!DEC$ ATTRIBUTES DLLEXPORT :: fortranFunc
use, intrinsic :: iso_c_binding, only: c_funptr, c_f_procpointer, c_double
implicit none
type(c_funptr), intent(in) :: getSquareFromPython
procedure(getSquare_proc), pointer :: getSquare
real(c_double) :: x = 2._c_double, xSquared
! associate the input C procedure pointer to a Fortran procedure pointer
call c_f_procpointer(cptr=getSquareFromPython, fptr=getSquare)
xSquared = getSquare(x)
write(*,*) "xSquared = ", xSquared
end subroutine fortranFunc
end module FortranFunc_mod
Python 函数可能如下所示,
import numpy as np
import ctypes as ct
# import dll and define result type
ff = ct.CDLL('FortranFunc_mod')
ff.fortranFunc.restype = None
# define and decorate Python callback with propoer ctypes
@ct.CFUNCTYPE( ct.c_double, ct.c_double ) # result type, argument type
def getSquareFromPython(x): return np.double(x**2)
# call Fortran function
ff.fortranFunc( getSquareFromPython )
但是,使用 ifort 编译此代码(已成功完成)然后运行 Python 代码会导致以下错误,
在这个简单的例子中我错过了什么?Fortran 和 python 代码之间是否需要额外的 C-wrapper 来定义回调原型?如果您还可以提供 C 等效代码来调用 Python 函数,那也会有所帮助。
慕妹3146593
相关分类