使用ctypes传递NumPy数组到Fortran时数据不匹配问题求解
问题原因
你遇到的数值错乱问题由三个核心不匹配导致:
- 浮点数据位宽不匹配
Fortran代码中声明的real默认是单精度(4字节,对应ctypesc_float、numpyfloat32),但你在Python中创建数组时指定dtype=float,实际是numpy默认的双精度float64(8字节),内存读取时位宽对应错误直接导致数值完全乱码。 - 整数数据位宽不匹配
coeff_flag数组在numpy创建时用dtype=int默认是int64(8字节),但Fortran默认integer和ctypes声明的c_int都是32位整数(4字节),同样存在位宽不匹配问题。 - 数组存储顺序与维度顺序不匹配
Fortran采用列优先(Column-major)的数组存储规则,且你声明的x数组维度是(goodval,num_mod_sel);但numpy默认是行优先(Row-major)存储,你创建的x数组维度是(num_mod_sel,goodval),内存布局完全不对应。
修复方案
仅需修改Python中数组创建的逻辑,匹配Fortran的类型和存储规则即可:
#Create some test data num_mod_sel = 4 goodval = 10 # 浮点数组指定dtype为float32匹配Fortran默认real x = np.full((num_mod_sel,goodval),999.,dtype=np.float32) x[:] = np.random.rand(num_mod_sel,goodval) # 转置后用Fortran顺序拷贝,维度和存储都匹配Fortran声明 x = x.T.copy(order='F') y = np.full(goodval,999.,dtype=np.float32) y[:] = np.random.rand(goodval) y = y.copy(order='F') coeff = np.empty(num_mod_sel,dtype=np.float32) # 整数数组指定dtype为int32匹配Fortran默认integer coeff_flag = np.empty(num_mod_sel,dtype=np.int32)
如果不想转置数组,也可以直接创建维度为(goodval, num_mod_sel)的数组并指定order='F',可根据你的业务逻辑选择更方便的写法。
内容的提问来源于stack exchange,提问作者BenT
相关产品推荐
相关产品推荐

