背景
因为编程需要使用python和fortran(或者c,c++)混合编程,所以进行了一些资料查询和实验。首先尝试了f2py,但是这个项目已经很久没有更新,为了以后兼容性考虑(后期可能会使用到c++),放弃了使用f2py。
平台
win7, gfortran 7.2 Anaconda5.3
ubuntu16.4,gfortran 5.4 Anaconda5.3
python调用fortran
主要根据pasuka的三篇博文,以及网络上转载的的一篇文章整理出使用ctypes的解决方法。
ctypes是python和c数据(也可以为fortran)交换的桥梁,直接上代码。
!test.f90
subroutine fun(n,p) Bind(C,Name="fun")
use,intrinsic :: iso_c_binding
implicit none
integer(c_int),value :: n !intent(in)可以加也可以不加
real(c_double) :: p(n) !intent(out)可以加也可以不加
integer(c_int) i
do i=1,n
p(i)=i*i
end do
return
end
此处定义了一个C类型的函数,名字叫fun,并且其数据类型定义均采用c_*来进行定义(输入输出数据,其它的不重要,但是为了保证数据运算时类型相同,一般定义一致),其中value关键字为必须的,该关键字规定了变量n是按值传递进该函数的(the actual argument is passed “by value”.),这样就与c的调用保持一致了。
编译命令为
gfortran test.f90 -fPIC -shared -o test.so
当然也可以加上其他的优化参数。
在python中调用的代码为。
import numpy as np
from numpy.ctypeslib import load_library,ndpointer
from ctypes import c_int
f = load_library("test.so",".")
n = 3
p = np.array([100,10,500],dtype='f8',order='f')
f.fun.argtypes=[c_int,ndpointer(dtype='f8',ndim=1)]
f.fun(n,p)
print(p)
load时,在linux下不需要加动态库的后缀名,在windows下必须加。
其余参见代码。
这样即可在python中调用fortran(调用c代码应该类似)。
后面尝试调用c++代码,因为有部分代码使用了c++的模板功能。
参考文献
https://docs.oracle.com/cd/E19205-01/819-5263/aevno/index.html