You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)布局不匹配,直接传递会导致数据读写混乱。

正确实现方案

核心要点

  1. 使用numpy创建连续内存、列主序的二维数组,确保与Fortran的内存布局一致。
  2. 直接传递numpy数组的ctypes指针,而非Python列表。
  3. 显式声明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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:27:40