我試圖讓Python使用Fortran DLL(通過referance調用)。運行Fortran 90代碼時,它運行良好,但不適用於Python;它只會提供「訪問衝突」錯誤或「調用的參數不足」。Ctypes Python訪問違規<> Fortran DLL
的Python代碼:
from ctypes import *
mydll = cdll.LoadLibrary("test.dll")
# This function works.
print mydll.XIT() # prints 0
mydll.GetInfo.argtypes = [POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_char_p)]
rm = c_int()
rf = c_int()
vm = (c_int * 5)()
vf = (c_int * 5)()
np = c_int(14)
p = (c_int * 14)()
filename = "test"
fn = c_char_p(filename)
nc = c_int(len(filename)) # length of string. (Hidden argument in Fortran)
# throws insufucient arguments
print mydll.GetInfo(rm,rf,vm,vf,np,p,fn,nc)
# throws access violation
print mydll.GetInfo(byref(rm),byref(rf),byref(vm),byref(vf),byref(np),byref(p),byref(fn),byref(nc))
的FORTRAN90代碼:
program test
implicit none
integer, parameter :: np = 14
integer :: rm, rf
integer, dimension(5) :: vm, vf
integer, dimension(np) :: p
character(len=80) :: fn
interface
integer function GetInfo(rm, rf, vm, vf, np, p, fn)
!dec$ attributes dllimport, stdcall, reference, decorate, alias:'GetInfo' :: GetInfo
implicit none
character(len=*), intent(in) :: fn
integer, intent(in) :: np
integer, intent(out) :: rm,rf
integer, intent(out), dimension(5) :: vm,vf
integer, intent(out), dimension(np) :: p
end function GetInfo
end interface
fn = "test"
print *, GetInfo(rm, rf, vm, vf, np, p, fn)
end program test
編輯: 我修改我的代碼,到現在還沒通字符串的長度作爲參考。我已將cdll切換到windll,並刪除了雙POINTER和byref()用法。另外,c_char_p已經是一個指針,所以它不需要POINTER。
你知道,這不像你的編譯器要你更多地編譯更長的變量名。只是說... –
@Stefano Fortran是別人的代碼,並且寫下了很長名字的傳統。在邊界的另一邊使用相同的名稱是有意義的。 –
@David Heffernan:原來的名字很短,你可以用它們作爲前綴。 – eryksun