如何将动态数组从Python传递到Fortran动态链接库

2024-09-29 01:26:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我在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子程序中使用动态数组

^{pr2}$

另外,我定义了一个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()    

回答python,在命令行Win7下返回时间那个:一个指针传递给解除分配指向无法解除分配的对象, 但第二次它给出了正确的答案

在Winxp命令行下,返回python脚本的第一个运行时间那个:一个指针传递给解除分配指向无法解除分配的对象, 但是第二次它给出了正确的答案,但是,它粉碎了!!!有时,它还返回:allocateable array is already allocated

我真的不知道为什么?如何使用动态数组?在


Tags: typepublicrealmassclassenddoublecols