سؤال

I got this simple module in 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

compiling it (on windows) gfortran test.f90 -o test.exe and running it gives, as expected:

 foo

I can also compile it using f2py: c:\Python27\python.exe c:\Python27\Scripts\f2py.py --fcompiler=gnu95 --compiler=mingw32 -c -m test \test.f90

When I run this Python script:

test.py:

from id_map import test

print "This should be 'foo':"
print test.foo()
print "was it?"

I get the following output:

This should be 'foo':

was it?

As you can see, the string that should be "foo" is empty. Why is this?

هل كانت مفيدة؟

المحلول

The problem here is with the len=* character declaration. you're telling the fortran compiler to accept any length string which was input. That's great except when you wrap it with f2py and have intent out, f2py needs to guess what length string to allocate and pass to your function and it has no way of doing that. (After all, what length string should it assume?).

It looks to me like f2py assumes a 0 length string. When you assign a bigger string to a smaller string in fortran, the result gets truncated (although I would need to go back and read the standard to find out if that could result memory errors). In any event, it looks like that's what the gnu compiler is doing.

If you change it to len=3, it works.

Alternatively, doing something like this can make this work for f2py without modifying the original code (except for some comments):

      !f2py character(len=256),intent(out):: chid
      character(len=*),intent(out):: chid          ! char. identifier
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top