经验:
fortran大约3个月
python-intermediate:在此之前从未在python中使用过ctypes模块
我在寻找一种方法,在python中使用fortran代码进行博士研究,然后使用matplotlib在运行中对可视化进行计算。在
THIS POST有帮助(这说明可以使用ctypes模块在python中使用/调用fortran代码,而且fortran函数有绑定到它们的替代名称,这在逻辑上对我来说是有意义的,尽管我不知道这是如何具体工作的。但我们明智地选择了我们的战斗。
然后this SO post也处理从python调用fortran函数的问题。在
我有所有的东西来制作一个最小的工作示例,another answer has already done。但我想看看输出机制和涉及实际浮点的数学运算。这是我做的测试用例。在
测试f90function prnt(s)
character(80):: s
logical :: prnt
print*, s
prnt = .true.
end function prnt
function sin_2(r)
real:: r,sin_2
sin_2 = sin(r)**2
end function sin_2
创建共享对象
^{pr2}$
编辑:由于某些原因,我的工作计算机需要-fPIC选项来编译
为了确保我的两个函数prnt和sin_2在某个地方,我检查了nm:$ nm test.so | tail -3
0000067f T prnt_
0000065c T sin_2_
U sinf@@GLIBC_2.0
到目前为止还不错。我的函数prnt和sin_2已经映射到库中的prnt_和{}。在
从python解释器调用fortran函数>>> from ctypes import byref, cdll, c_float,c_char_p
>>> t = cdll.LoadLibrary('./test.so')
>>> c = c_char_p("Mary had a little lamb")
>>> t.prnt_('Mary had a little lamb')
Mary had a little lambe
1
>>> t.prnt_("Mary had a little lamb")
Mary had a little lambe
1
>>> t.prnt_(c)
Mary had a little lambe[� .prnt_(c)
1
我假设每个输出末尾打印的1是python让我知道t.prnt_的布尔输出是.true.。
我有点担心当我切换到字符串的正确数据类型时,t.prnt_的情况会变得更糟。文字打印正常,只在末尾加一个e。这是EOL角色吗?在
然后是t.sin_2_函数。我决定用它来计算sin(4.56)**2。事情是这样的->>> f = c_float(4.56)
>>> t.sin_2_(4.56)
Traceback (most recent call last):
File "", line 1, in
ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1
>>> t.sin_2_(f)
Segmentation fault (core dumped)
我哪里出错了?我试图解释我是如何解决这个问题的,这样,如果我在某个地方犯了明显的错误,那就很明显了。
与其他SO帖子的大量链接是为了帮助那些和我现在提出同样问题的人。在