我想设置一个工作流程,使用Cython在Windows机器上从Python调用Fortran例程。
经过一番搜索,我找到了以下资料:http://www.fortran90.org/src/best-practices.html#interfacing-with-c 和 https://stackoverflow.com/tags/fortran-iso-c-binding/info
还有一些代码片段:
Fortran端:
pygfunc.h:
void c_gfunc(double x, int n, int m, double *a, double *b, double *c);
pygfunc.f90
module gfunc1_interface
use iso_c_binding
use gfunc_module
implicit none
contains
subroutine c_gfunc(x, n, m, a, b, c) bind(c)
real(C_FLOAT), intent(in), value :: x
integer(C_INT), intent(in), value :: n, m
type(C_PTR), intent(in), value :: a, b
type(C_PTR), value :: c
real(C_FLOAT), dimension(:), pointer :: fa, fb
real(C_FLOAT), dimension(:,:), pointer :: fc
call c_f_pointer(a, fa, (/ n /))
call c_f_pointer(b, fb, (/ m /))
call c_f_pointer(c, fc, (/ n, m /))
call gfunc(x, fa, fb, fc)
end subroutine
end module
gfunc.f90
module gfunc_module
use iso_c_binding
implicit none
contains
subroutine gfunc(x, a, b, c)
real, intent(in) :: x
real, dimension(:), intent(in) :: a, b
real, dimension(:,:), intent(out) :: c
integer :: i, j, n, m
n = size(a)
m = size(b)
do j=1,m
do i=1,n
c(i,j) = exp(-x * (a(i)**2 + b(j)**2))
end do
end do
end subroutine
end module
Cython端:
pygfunc.pyx
cimport numpy as cnp
import numpy as np
cdef extern from "./pygfunc.h":
void c_gfunc(double, int, int, double *, double *, double *)
cdef extern from "./pygfunc.h":
pass
def f(float x, a=-10.0, b=10.0, n=100):
cdef cnp.ndarray ax, c
ax = np.arange(a, b, (b-a)/float(n))
n = ax.shape[0]
c = np.ndarray((n,n), dtype=np.float64, order='F')
c_gfunc(x, n, n, <double *> ax.data, <double *> ax.data, <double *> c.data)
return c
以及安装文件:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
ext_modules = [Extension('pygfunc', ['pygfunc.pyx'])]
setup(
name = 'pygfunc',
include_dirs = [np.get_include()],
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules )
所有文件都在一个目录中。
Fortran文件编译(使用NAG Fortran Builder),pygfunc编译。
但将它们链接起来会出现以下错误:
error LNK2019:未解析的外部符号_c_gfunc,该符号在函数___pyx_pf_7pygfunc_f中被引用
当然还有:
fatal error LNK1120:1个无法解析的外部
我漏掉了什么?或者说这种Python和Fortran之间的工作流程设置从一开始就注定要失败吗?
谢谢 Martin
c_gfunc
,或者以Fortran过程而不是C过程的方式调用它吗? - Vladimir F Героям славаctypes
更接近于Cython
,虽然这并不是解决问题的方法。Fortran代码可以保持原样。 - Vladimir F Героям слава