2013-06-27 34 views
4

返回從FORTRAN子程序蟒蛇文本字符串我用Fortran這個簡單的模塊:使用f2py

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 

編譯它(在Windows上)gfortran test.f90 -o test.exe並運行它給,符合市場預期:

foo 

我也可以用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?" 

我得到以下輸出:

This should be 'foo': 

was it? 

正如你可以看到,該字符串應該是「foo」是空的。爲什麼是這樣?

回答

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 
+0

謝謝!你是絕對正確的。你知道我是否可以告訴f2py承擔其他事情嗎?我寧願不去修改我的遺留代碼,除非它真的有必要...... – Paul

+0

@保羅 - 我對此表示懷疑。你可以嘗試使用'f2py'生成一個簽名文件,然後編輯它(儘管我從來沒有打算做這樣的事情......)。你也可以用'intent(inout)'做一個小魔術,儘管我不知道python字符串怎麼樣,因爲它們是不可變的... – mgilson

+0

找到了這個問題的答案。如果我在聲明'!f2py字符(len = 256),intent(out):: chid'上面添加這一行,它會起作用!它看起來更好,如果我刪除Python中的空白字符串'test.foo()。strip()' – Paul