使用f2py将文本字符串从fortran子例程返回到python

Pau*_*aul 4 python fortran f2py

我在Fortran中有这个简单的模块:

test.f90:

module test
   implicit none
contains

   subroutine foo(chid)
      implicit none
      character(len=*),intent(out):: chid          ! char. identifier
      chid = "foo"
   end subroutine foo
end module test

program bar
   use test
   character(len=20) text
   call foo(text)
   write(*,*) text
end program bar
Run Code Online (Sandbox Code Playgroud)

编译它(在Windows上)gfortran test.f90 -o test.exe并运行它,如预期的那样:

 foo
Run Code Online (Sandbox Code Playgroud)

我也可以使用f2py编译它: c:\Python27\python.exe c:\Python27\Scripts\f2py.py --fcompiler=gnu95 --compiler=mingw32 -c -m test \test.f90

当我运行这个Python脚本时:

test.py:

from id_map import test

print "This should be 'foo':"
print test.foo()
print "was it?"
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

This should be 'foo':

was it?
Run Code Online (Sandbox Code Playgroud)

如您所见,应为"foo"的字符串为空.为什么是这样?

mgi*_*son 5

这里的问题是len=*字符声明.你告诉fortran编译器接受输入的任何长度字符串.这很好,除非你用它包装f2py并有意图out,f2py需要猜测分配的长度字符串并传递给你的函数,它无法做到这一点.(毕竟,它应该采用什么长度的字符串?).

在我看来,f2py假设一个0长度的字符串.当你在fortran中为较小的字符串分配一个较大的字符串时,结果会被截断(尽管我需要返回并阅读标准以查明是否会导致内存错误).无论如何,看起来这就是gnu编译器正在做的事情.

如果你改成它len=3,它的工作原理.

或者,执行此类操作可以使f2py无需修改原始代码(除了一些注释):

      !f2py character(len=256),intent(out):: chid
      character(len=*),intent(out):: chid          ! char. identifier
Run Code Online (Sandbox Code Playgroud)