我的目标是从fortran中的python numpy数组中打印第二个字符串,但我只打印第一个字符,并且它也不一定是正确的字符串。
有谁能告诉我将完整字符串数组传递给fortran的正确方法是什么?
代码如下:
testpy.py
import numpy as np
import testa4
strvar = np.asarray(['aa','bb','cc'], dtype = np.dtype('a2'))
testa4.testa4(strvar)
testa4.f90
subroutine testa4(strvar)
implicit none
character(len=2), intent(in) :: strvar(3)
!character*2 does not work here - why?
print *, strvar(2)
end subroutine testa4
已编译
f2py -c -m testa4 testa4.f90
输出上述代码
c
所需的输出
bb
答案 0 :(得分:3)
我不知道如何使用f2py
来做到这一点。但可以使用ctypes
完成。你得到一个字符数组,但你可以很容易地将它转换为字符串。
subroutine testa4(strvar) bind(C, name='testa4')
use iso_c_binding
implicit none
character(len=1,kind=c_char), intent(in) :: strvar(2,3)
print *, strvar(:,2)
end subroutine testa4
编译:{{1}}
gfortran -shared -fPIC testa4.f90 -o testa4.so
运行:
import numpy as np
import ctypes
testa4 = ctypes.CDLL("./testa4.so")
strvar = np.asarray(['aa','bb','cc'], dtype = np.dtype('a2'))
strvar_p = ctypes.c_void_p(strvar.ctypes.data)
testa4.testa4(strvar_p)
答案 1 :(得分:3)
根据documentation,f2py喜欢用dtype ='c'传递的字符串数组(即'| S1')。这会让你成为那里的一部分,虽然在幕后有一些奇怪的阵列形状(例如,在我的很多测试中,我发现fortran会保留2个字符的长度,但是将6个字符解释为指示一个2x6阵列,所以我会在输出中得到随机存储器)。这(据我所知),要求您将Fortran数组视为2D字符数组(而不是1D“字符串”数组)。不幸的是,我无法让它采取假定的形状,并最终将字符串的数量作为参数传递。
我很确定我错过了一些相当明显的东西,但这应该暂时有效。至于为什么CHARACTER * 2不起作用......我真的不知道。
MODULE char_test
CONTAINS
SUBROUTINE print_strings(strings, n_strs)
IMPLICIT NONE
! Inputs
INTEGER, INTENT(IN) :: n_strs
CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
!f2py INTEGER, INTENT(IN) :: n_strs
!f2py CHARACTER, INTENT(IN), DIMENSION(2,n_strs) :: strings
! Misc.
INTEGER*4 :: j
DO j=1, n_strs
WRITE(*,*) strings(:,j)
END DO
END SUBROUTINE print_strings
END MODULE char_test
----------------
import numpy as np
import char_test as ct
strings = np.array(['aa', 'bb', 'cc'], dtype='c').T
ct.char_test.print_strings(strings, strings.shape[1])
strings = np.array(['ab', 'cd', 'ef'], dtype='c').T
ct.char_test.print_strings(strings, strings.shape[1])
-->python run_char_test.py
aa
bb
cc
ab
cd
ef
答案 2 :(得分:0)
不是答案,但是评论时间太长:也许这会有所帮助..
在你的第一种情况下传递给fortran的是由于某种原因每个字符串的第一个字符:
'abc'
在fortran中,在长度为2的数组中结束为' ab' ,' c'。如果你严格地使用长度一个字符串阵列一切都很好,我想。不幸的是你不能伪造系统并在python ['a','a','b','b'..
中分成单个字符数组 - 如果数组长度不匹配则会抛出错误。
关于第二个问题,如果您使用
声明 character*2
符号,它实际上只是传递一个常规的python字符串列表:
testa4.testa4(['aa','bb','cc'])
(如果您尝试使用numpy字符串数组,现在会抛出错误。)。字符串必须是正确的正确长度,否则它也会引发错误。