F2py转换字符(*)分段错误

时间:2017-04-06 08:40:39

标签: python arrays fortran character f2py

我正在尝试使用f3py在Python 3.5中使用Fortran90数值模型。

f2py -c module.f90 -m mod --fcompiler=gfortran

该模型是一个包含变量,函数和子例程的Fortran模块。我在这里发布了一个具有数值模型所有功能的代码示例

module modul

implicit none
integer :: inte
real :: re
integer, dimension(3) :: array
CHARACTER(*), PARAMETER :: chara = "helloWorld"

contains
    integer function fun()
        fun = array(1) + array(2) + array(3)
    end function

    subroutine subrout(a,b)
        real, intent(out) :: b
        integer, intent(out) :: a
        a = inte + fun()
        b = re
        write(*,*) chara
    end subroutine subrout

end module modul

使用f2py转换代码的工作正常但是,当我在Python中导入模块时,我收到了分段错误错误

>>> import mod
Segmentation fault (core dumped)

我意识到问题取决于字符数组的未指定维度

CHARACTER(*), PARAMETER :: chara = "helloWorld"

因为,如果我删除那行代码或者为数组指定一个固定的维度(如CHARACTER(20)),该模块在Python中正常工作。

1。有没有办法让它工作而不修改Fortran代码     (模型很长很复杂,如果可能的话,我不想这样做     工作)?

字符数组用于在代码中定义字符串(如错误消息)并处理文件的输入/输出。解决问题的一种方法(如果对问题1没有答案)可以为所有字符串定义固定的最大维度(即INTEGER,PARAMETER :: lenChar = 100),然后使用

CHARACTER(lenChar), PARAMETER :: chara

而不是之前的声明。在这种情况下,模块在Python中成功导入,但是当我尝试修改数组内容时,它需要输入lenChar long(同样的问题出现在其他类型的数组中,如INTEGER或REAL,并且不依赖于PARAMETER属性)

mod.modul.chara = "hello"
0-th dimension must be fixed to 100 but got 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
SystemError: error return without exception set

这是模型需要处理的操作,因为“chara”可能是数据的路径,需要在运行时进行初始化。

2。如果对问题(1)没有答案并且我需要以这种方式进行,我怎样才能为数组分配一个比数组长度短的输入?

System information:
OS: Ubuntu 16.04
Python 3.5.2
f2py Version:     2
numpy Version: 1.12.1
GNU Fortran (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

2 个答案:

答案 0 :(得分:1)

您似乎混淆了可变长度字符串(无论可能是什么,类似于Fortran 2003中的字符串),字符串常量和伪参数,它们会占用您传递的长度。可能你想要:

subroutine sub(ch)
  character(*), intent(in) :: ch

  print *, ch
end

这与您的示例完全不同。此处参数ch将接受您传递的任意长度的字符串。

问题在于假定的长度字符常量。这足以触发错误

module m
  CHARACTER(*), PARAMETER :: chara = "helloWorld"
end module m

这不是字符数组,它是假定长度的标量字符串。

完全相同
module m
  CHARACTER(10), PARAMETER :: chara = "helloWorld"
end module m

唯一的区别是,如果您懒得手动计算长度(或者您不时地更改它),编译器会在前一种情况下自动获取长度。

后一版本在f2py中正常运行:

f2py -c -m f2pychar f2pychar.f90 

ipython

In [1]: import f2pychar 

In [2]: print f2pychar.modul.chara
['h' 'e' 'l' 'l' 'o' 'W' 'o' 'r' 'l' 'd']

F2py应该理解它,但似乎没有。这是f2py中的一个严重错误。只需手动输入长度,如上面的后一个示例所示。没有区别,代码是euivalent。

给你的号码(2)。它不是一个数组(在Fortran中)。数组规则不适用于此处。但更重要的是,它是一个常数,你不能分配任何东西,所以我真的不明白你的意思。如果你有一个字符变量,你可以分配一个没有问题的较短字符串:

character(10) :: ch = "abcd"

答案 1 :(得分:1)

回答问题2:

fortran中的字符串被视为f2py中的字符数组。因此,在您的情况下,mod.modul.chara是一个100个字符的数组(取决于fortran中指定的长度)。要将'hello'之类的内容提供给句柄,您可以执行以下操作:

for i,j in enumerate('hello'):
    mod.modul.chara[i]=j

这应该让你传递字符串。