Python向Fortran传递可修改二维数组遇AttributeError问题求解
解决Python与Fortran间可修改二维数组传递的问题
问题背景
已掌握一维可修改数组从Python传递到Fortran的方法,现需实现二维数组的双向传递。Fortran子程序定义如下:
!dec$ attributes dllexport :: getlincon subroutine getlincon(nr, lhs) integer, intent(in ) :: nr real(8), intent(out) :: lhs(nr,*)
Python侧尝试传递二维数组时,因使用列表嵌套numpy数组导致报错:
AttributeError: 'list' object has no attribute 'ctypes'
错误原因
Python列表是离散元素的容器,并非连续内存块,不具备ctypes属性;且Fortran采用列主序(column-major)存储二维数组,与numpy默认的行主序(row-major)布局不匹配,直接传递会导致数据读写混乱。
正确实现方案
核心要点
- 使用numpy创建连续内存、列主序的二维数组,确保与Fortran的内存布局一致。
- 直接传递numpy数组的ctypes指针,而非Python列表。
- 显式声明Fortran函数的参数类型,避免隐式转换错误。
修正后的Python代码
import ctypes as ct import numpy as np # 加载编译后的Fortran动态链接库 lib = ct.CDLL('x64\\Debug\\fortranobj.dll') # 获取模块中子程序的编译后名称(Intel Fortran模块子程序命名规则) fl = getattr(lib, 'FTN_OBJFUN_MOD_mp_GETLINCON') # 显式声明函数参数类型,强制类型检查 fl.argtypes = [ct.POINTER(ct.c_int), ct.POINTER(ct.c_double)] # 定义数组维度:nr=3行,nc=2列 nc = ct.c_int(2) nr = ct.c_int(3) # 创建Fortran列主序的二维数组,双精度浮点,初始化为0 # 形状为(nr, nc),匹配Fortran子程序中lhs(nr,*)的行维度 lhs = np.zeros((nr.value, nc.value), dtype=np.float64, order='F') # 调用Fortran子程序:传递nr的引用,以及数组的ctypes指针 fl(ct.byref(nr), lhs.ctypes.data_as(ct.POINTER(ct.c_double))) # 此时lhs已被Fortran修改,可直接使用 print("修改后的二维数组:") print(lhs)
关键细节说明
order='F':指定numpy数组按Fortran列主序存储,确保Fortran能正确解析数组的行列结构。lhs.ctypes.data_as(...):将numpy数组的内存地址转换为ctypes双精度指针,符合Fortran对数组参数的接收要求。fl.argtypes:显式声明参数类型,让ctypes自动校验传入参数的类型,避免因隐式转换导致的内存错误。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

