我試圖將參數傳遞給使用ctypes的共享庫中的Fortran子例程。現在,這裏是我的簡單的Fortran代碼:使用ctypes將python字符串傳遞給Fortran子例程
MODULE test_module
INCLUDES
SUBROUTINE fstr_test(file_or_extension, ierr, iopen)
IMPLICIT NONE
INTEGER, INTENT(out) :: ierr
INTEGER, OPTIONAL :: iopen
CHARACTER(LEN=*), INTENT(in) :: file_or_extension
WRITE(6,*) file_or_extension,ierr,iopen
RETURN
END SUBROUTINE fstr_test
END MODULE test_module
我
gcc -shared -fPIC -o libtest.o fstr_test.f90
這似乎做工精細編譯這個,我其實可以加載共享庫在Python 3.這裏的非崩潰代碼:
from ctypes import *
libtest = cdll.LoadLibrary("libtest.so")
f = libtest.test_module_MOD__fstr_test
file = b'wout_li383.nc'
ierr = c_int(0)
iopen = c_int(0)
cfile=c_char_p(b"test_str")
f(cfile,byref(ierr),byref(iopen))
但是,我似乎無法正確傳遞字符串。在上面的表單中,字符串是空的,兩個整數正確地打印到控制檯。基本上,我所取得的唯一進展是讓Python崩潰。我在這裏嘗試瞭解決方案:
Passing string to Fortran DLL using ctypes and Python
,但它似乎並沒有爲我工作,也許是因爲它是Python 2?
例如
f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(c,byref(ierr),byref(iopen))
不會崩潰的內核,但字符串是空的。改爲byref:
f.argtype = [c_char_p,c_int_c_int]
c = c_char_p(b"test.txt")
f(byref(c),byref(ierr),byref(iopen))
同樣的效果。現在,如果我嘗試通過添加length參數來傳遞長度並傳遞它,我會收到一條「Dead Kernel」的消息,我必須重新啓動內核。本身沒有錯誤信息。
f.argtype = [c_char_p,c_int,c_int_c_int]
file = b'text.txt'
c = c_char_p(file)
c_len = c_int(len(file))
f(c,byref(c_len),byref(ierr),byref(iopen))
希望澄清。我沒有收到錯誤信息,內核剛剛死亡。
鏈接的問題的答案是爲字符串的長度傳遞一個「隱藏的」參數(當不使用C可互操作的字符變量時常用的方法)。你不這樣做? – francescalus
爲什麼它不能工作?錯誤信息?錯誤的結果?給他們看。 –
如果我將字符串長度作爲隱藏變量包含,則內核崩潰。 – Lazer