python fortran c 混合编程

2018-10-19  本文已影响0人  uruzu

背景

因为编程需要使用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++的模板功能。

参考文献

  1. https://www.cnblogs.com/pasuka/p/3958302.html
  2. https://blog.csdn.net/MCANDML/article/details/80426914
  3. https://docs.oracle.com/cd/E19205-01/819-5263/aevno/index.html
上一篇下一篇

猜你喜欢

热点阅读