我在Python中调用fortran dll时遇到了一些麻烦,并且真的需要一些帮助和建议。 我的问题是将动态数组传递给函数(由我的Fortran DLL提供)。
例如,我有一个带动态数组的类型:
Module Class_Rotor
Implicit None
Type,Public ::Type_Rotor
Real(kind=8),Public::Mass
Real(kind=8),Allocatable,Public::Lamda(:,:)
End Type Type_Rotor
End Module Class_Rotor
Module Class_Trim
Implicit None
Type,Public::Type_Trim
Real(kind=8),Public::COLL
Real(kind=8),Public::LNGCYC
End Type Type_Trim
End Module Class_Trim
我想在fortran子程序中使用动态数组
Subroutine CalculateRotor(Trim,Rotor)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"CalculateRotor" :: CalculateRotor
Use Class_Rotor
Use Class_Trim
TYPE(Type_Trim),Intent(in)::Trim
TYPE(Type_Rotor),Intent(inout)::Rotor
Rotor%Mass = Trim%COLL + Trim%LNGCYC
End Subroutine CalculateRotor
Subroutine CalculateTrim(Rotor,Trim)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"CalculateTrim" :: CalculateTrim
Use Class_Rotor
Use Class_Trim
TYPE(Type_Rotor),Intent(in)::Rotor
TYPE(Type_Trim),Intent(inout)::Trim
Trim%COLL = Rotor%Mass+Rotor%Lamda(2,2)
End Subroutine CalculateTrim
另外,我定义了一个sunroutine Alc来分配Rotor%Lamda的空间,并将值传递给它。
Subroutine Alc(Rotor,n,LamArray)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, REFERENCE, MIXED_STR_LEN_ARG, ALIAS:"Alc" :: Alc
Use Class_Rotor
TYPE(Type_Rotor),intent(inout):: Rotor
Integer(kind=4)::I,J
Integer(kind=4),intent(in)::n
Real(kind = 8),DIMENSION(n,n),intent(in)::LamArray
IF(Allocated(Rotor%Lamda))Then
DeAllocate(Rotor%Lamda)
ENDIF
Allocate(Rotor%Lamda(n,n))
Do I=1,n
Do J=1,n
Rotor%Lamda(I,J)=LamArray(I,J)
EndDo
EndDo
End Subroutine Alc
我试着这样: 新的Fortran DLL项目(vs2010 + IVF),然后我在python中使用这个DLL:
from ctypes import *
import numpy as np
from numpy.ctypeslib import load_library,ndpointer
class Type_Rotor(Structure):
_fields_ = [
('Mass', c_double),
('Lamda', POINTER(c_double)),
]
def __init__(self,cols):
self.cols_count = cols
pc = (POINTER(c_double)*cols*cols)()
self.Lamda = cast(pc,POINTER(c_double))
class Type_Trim(Structure):
_fields_ = [
('COLL', c_double),
('LNGCYC', c_double),
]
def run():
mydll = windll.LoadLibrary('Dll3.dll')
CalculateRotor = mydll.CalculateRotor
CalculateTrim = mydll.CalculateTrim
Rotor = Type_Rotor(3)
Trim = Type_Trim()
Rotor.Mass = 1.0
temp = (c_double *3*3) ((1,2,3),(4,5,6),(7,8,9))
Trim.COLL = 11.0
Trim.LNGCYC = -3.0
mydll.Alc(byref(Rotor),byref(c_int(Rotor.cols_count)),byref(temp))
for i in range(15):
CalculateRotor(byref(Trim), byref(Rotor))
print Trim.COLL,Trim.LNGCYC,Rotor.Mass
CalculateTrim(byref(Rotor), byref(Trim))
print Trim.COLL,Trim.LNGCYC,Rotor.Mass
if __name__=="__main__":
run()
在Win7下,第一次使用命令行运行python脚本,返回以下答案:传递给DeAllocate的指针指向一个无法解除分配的对象,
但第二次给出了正确的答案
在Winxp下,第一次使用命令行运行python脚本,返回以下答案:传递给DeAllocate的指针指向一个无法释放的对象, 但第二次它给出了正确的答案,但是,然后它粉碎!!! somtimes,它也返回:可分配的数组已经分配
我真的不知道为什么?以及如何使用动态数组?