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