【发布时间】:2014-03-14 11:44:08
【问题描述】:
我想设置一个工作流,以便在 Windows 机器上使用 Cython 从 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 编译
但链接它们会引发:
错误 LNK2019:引用了未解析的外部符号 _c_gfunc 在函数___pyx_pf_7pygfunc_f
当然还有:
致命错误 LNK1120:1 个未解决的外部问题
我错过了什么?还是这种在 Python 和 Fortran 之间建立工作流的方式从一开始就该死?
THX 马丁
【问题讨论】:
-
这很奇怪。你不是在没有显式接口的情况下从 Fortran 的某个地方调用
c_gfunc,或者以其他方式作为 Fortran 过程,而不是 C 过程吗? -
抱歉,我没听懂
-
不能解决您的问题,但如果您不知道,您还可以考虑另一种选择:f2py。
-
没关系,它不会导致任何地方。显然 Cython 根本没有使用您的 Fortran 目标文件。我对 Cython 的了解不足以帮助你。我能够使用
ctypes运行您的代码。 -
@steabert 也没有解决,但我认为
ctypes是一种更接近Cython的方法。 Fortran 代码可以保持原样。
标签: python fortran cython fortran-iso-c-binding