当前位置: 首页 > ds >正文

在Fortran和Python之间共享变量

在Fortran和Python之间共享变量

在Fortran工程中与Python共享标量变量和数组变量,可以通过以下几种方法实现。我将介绍最常用的几种方法,包括使用Python的字典作为中介。

1. 使用f2py (NumPy的Fortran接口)

这是最直接的方法,f2py允许Fortran和Python之间直接共享内存。

Fortran端代码 (shared_vars.f90)

module shared_varsimplicit nonereal(8) :: scalar_varreal(8), allocatable :: array_var(:,:)containssubroutine init_array(n, m)integer, intent(in) :: n, mallocate(array_var(n, m))array_var = 0.0d0end subroutine init_arraysubroutine print_vars()print *, "Scalar var:", scalar_varprint *, "Array var:"print *, array_varend subroutine print_vars
end module shared_vars

Python端代码

import numpy as np
import f2py_wrapper  # 这是编译后的模块# 编译Fortran代码
# 命令行执行: f2py -c -m f2py_wrapper shared_vars.f90# 创建字典作为中介
var_dict = {'scalar': 3.14,'array': np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float64)
}# 传递变量给Fortran
f2py_wrapper.shared_vars.scalar_var = var_dict['scalar']
f2py_wrapper.shared_vars.init_array(*var_dict['array'].shape)
f2py_wrapper.shared_vars.array_var[:,:] = var_dict['array']# 调用Fortran打印
f2py_wrapper.shared_vars.print_vars()# 修改Fortran中的变量
f2py_wrapper.shared_vars.scalar_var = 6.28
f2py_wrapper.shared_vars.array_var[0,0] = 10.0# 从Fortran获取更新后的值
var_dict['scalar'] = f2py_wrapper.shared_vars.scalar_var
var_dict['array'] = f2py_wrapper.shared_vars.array_var.copy()print("Updated Python dict:", var_dict)

2. 使用ctypes库

这种方法提供了更底层的控制。

Fortran端代码 (ctypes_shared.f90)

module ctypes_shareduse, intrinsic :: iso_c_bindingimplicit nonereal(c_double), bind(C) :: c_scalar_vartype(c_ptr), bind(C) :: c_array_ptrinteger(c_int), bind(C) :: c_array_sizecontainssubroutine print_shared_vars() bind(C)use, intrinsic :: iso_c_bindingreal(c_double), pointer :: f_array(:)print *, "Scalar var:", c_scalar_varif (c_associated(c_array_ptr)) thencall c_f_pointer(c_array_ptr, f_array, [c_array_size])print *, "Array var:"print *, f_arrayelseprint *, "Array not allocated"end ifend subroutine print_shared_vars
end module ctypes_shared

Python端代码

import ctypes
import numpy as np
from numpy.ctypeslib import ndpointer# 加载共享库
lib = ctypes.CDLL('./ctypes_shared.so')  # 需要先编译Fortran代码# 设置参数和返回类型
lib.print_shared_vars.argtypes = None
lib.print_shared_vars.restype = None# 创建字典
var_dict = {'scalar': ctypes.c_double(3.14),'array': np.array([1.0, 2.0, 3.0, 4.0], dtype=np.float64)
}# 设置标量变量
lib.c_scalar_var = var_dict['scalar']# 设置数组变量
array_ptr = var_dict['array'].ctypes.data_as(ctypes.POINTER(ctypes.c_double))
lib.c_array_ptr = array_ptr
lib.c_array_size = ctypes.c_int(len(var_dict['array']))# 调用Fortran打印
lib.print_shared_vars()# 修改Fortran中的变量
lib.c_scalar_var = 6.28
var_dict['array'][0] = 10.0  # 直接修改,因为内存是共享的# 再次打印
lib.print_shared_vars()# 更新字典中的标量值
var_dict['scalar'] = lib.c_scalar_var

3. 使用Python的字典作为中介的完整示例

下面是一个更完整的示例,展示如何通过字典在两个方向传递数据:

import numpy as npdef fortran_to_dict(fortran_module):"""将Fortran模块中的变量提取到字典"""var_dict = {}# 获取标量变量if hasattr(fortran_module, 'scalar_var'):var_dict['scalar'] = fortran_module.scalar_var# 获取数组变量if hasattr(fortran_module, 'array_var'):var_dict['array'] = fortran_module.array_var.copy()return var_dictdef dict_to_fortran(var_dict, fortran_module):"""将字典中的变量传递到Fortran模块"""# 设置标量变量if 'scalar' in var_dict:fortran_module.scalar_var = var_dict['scalar']# 设置数组变量if 'array' in var_dict:arr = var_dict['array']if not hasattr(fortran_module, 'array_var') or \fortran_module.array_var.shape != arr.shape:fortran_module.init_array(*arr.shape)fortran_module.array_var[:,:] = arr# 使用示例
var_dict = {'scalar': 3.14,'array': np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float64)
}# 传递到Fortran
dict_to_fortran(var_dict, f2py_wrapper.shared_vars)# 从Fortran获取
updated_dict = fortran_to_dict(f2py_wrapper.shared_vars)

编译说明

对于上述方法,需要先编译Fortran代码:

  1. f2py方法:

    f2py -c -m f2py_wrapper shared_vars.f90
    
  2. ctypes方法:

    gfortran -shared -fPIC -o ctypes_shared.so ctypes_shared.f90
    

注意事项

  1. 内存管理:数组在Fortran和Python之间共享时,要注意内存分配和释放
  2. 数据类型匹配:确保两端的变量类型一致
  3. 数组顺序:Fortran是列优先,Python/NumPy默认是行优先
  4. 线程安全:如果涉及多线程,需要确保同步

以上方法提供了灵活的方式在Fortran和Python之间共享数据,通过Python字典作为中介可以更好地组织和管理这些共享变量。

http://www.xdnf.cn/news/758.html

相关文章:

  • 一个Nuxt3 SSR服务端渲染简洁好用的开源个人博客系统 交互设计体验简单 腾讯markdown编辑器 支持drawio画图
  • STM32开发过程中碰到的问题总结 - 4
  • [Windows] 星光桌面精灵 V0.5
  • OSI七层模型
  • 开源项目FastAPI-MCP:一键API转换MCP服务
  • 信创时代编程开发语言选择指南:国产替代背景下的技术路径与实践建议
  • MIT6.S081-lab4前置
  • ROS机器人开发实践->机器人建模与仿真
  • LeetCode每日一题4.20
  • SSRF学习
  • 【Agent】AI智能体评测基座AgentCLUE-General
  • 21.Chromium指纹浏览器开发教程之触摸屏点指纹定制
  • RHCSA Linux 系统文件内容显示2
  • 云梦数字化系统 介绍
  • 2025 第十六届蓝桥杯Java B组
  • 信号的概念
  • 《软件设计师》复习笔记(2.4)——输入输出、中断、总线、可靠性
  • TensorFlow介绍
  • 漫游git rebase + 浅谈git checkout和git branch -f的分支命令
  • Linux内核哈希表学习笔记
  • Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架
  • 数字化时代下的工业物联网智能体开发平台策略
  • Vue3中provide和inject数据修改规则
  • 代码随想录训练营第36天 ||1049. 最后一块石头的重量 II 494. 目标和 474. 一和零
  • C++——智能指针
  • 防抖与节流的理解与应用
  • 【C++】win 10 / win 11:Dev-C++ 下载与安装
  • 数据结构实验7.1:二叉树的遍历
  • C语言strlen和sizeof区分
  • Cadence学习笔记之---库元件制作、元件放置