如何用ctypes封装Fortran为Python3.12+可分发包(基于meson-python)
解决方案:用ctypes+Meson-Python构建可pip安装的Fortran-Python包(Python3.12+)
针对你遇到的setuptools不支持Fortran编译、pip安装无法触发Meson流程的问题,以下是完整的可落地方案,纯用ctypes实现封装,兼容Python3.12+并可发布至PyPI。
1. 标准化项目结构
调整目录结构,让Meson编译的共享库能和Python模块同目录安装:
fortran2python/ ├── src/ │ ├── fortran/ │ │ └── mymath.f90 # 你的Fortran代码 │ └── python/ │ └── fortran2python/ │ ├── __init__.py # 包入口 │ └── _core.py # ctypes封装逻辑 ├── meson.build # Meson编译配置 ├── pyproject.toml # PEP 518构建配置 └── README.md # 项目说明(可选)
2. 配置pyproject.toml
使用meson-python作为PEP 517构建后端,让pip自动触发Meson编译流程:
[build-system] requires = ["meson-python>=0.13.0", "meson>=1.2.0"] build-backend = "mesonpy" [project] name = "fortran2python" version = "0.1.0" authors = [{"name" = "Your Name", "email" = "your@email.com"}] description = "Python wrapper for Fortran code using pure ctypes" readme = "README.md" requires-python = ">=3.12" classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Fortran", "License :: OSI Approved :: MIT License", ]
3. 编写meson.build编译配置
指定Fortran编译规则,将共享库安装到Python包目录下:
# 项目元信息 project('fortran2python', 'fortran', 'python', version: '0.1.0', default_options: ['buildtype=release']) # 编译Fortran为共享库 fortran_lib = shared_library( 'mymath', sources: 'src/fortran/mymath.f90', install: true, install_dir: 'fortran2python' # 库将和Python模块同目录安装 ) # 安装Python模块文件 python_install_sources = [ 'src/python/fortran2python/__init__.py', 'src/python/fortran2python/_core.py' ] install_data( python_install_sources, install_dir: 'fortran2python' )
4. 纯ctypes封装Python模块
示例Fortran代码(src/fortran/mymath.f90)
module mymath implicit none contains function add(a, b) result(res) integer, intent(in) :: a, b integer :: res res = a + b end function add function multiply(a, b) result(res) real, intent(in) :: a, b real :: res res = a * b end function multiply end module mymath
ctypes封装逻辑(src/python/fortran2python/_core.py)
处理跨平台库路径,声明函数签名并暴露给Python:
import ctypes import os import sys from importlib.resources import files def _load_library(): # 适配不同平台的共享库后缀 lib_name = 'mymath' if os.name == 'nt': lib_ext = '.dll' elif sys.platform == 'darwin': lib_ext = '.dylib' else: lib_ext = '.so' # 获取安装后的库路径 lib_path = files('fortran2python').joinpath(f'{lib_name}{lib_ext}') # 加载共享库 lib = ctypes.CDLL(str(lib_path)) # 声明Fortran函数的参数类型和返回值类型 lib.add.argtypes = [ctypes.c_int, ctypes.c_int] lib.add.restype = ctypes.c_int lib.multiply.argtypes = [ctypes.c_float, ctypes.c_float] lib.multiply.restype = ctypes.c_float return lib # 预加载库并暴露函数 _lib = _load_library() add = _lib.add multiply = _lib.multiply
包入口文件(src/python/fortran2python/__init__.py)
from ._core import add, multiply __version__ = "0.1.0"
5. 测试安装与验证
# 创建Python3.12+虚拟环境 python3.12 -m venv venv source venv/bin/activate # Windows系统执行:venv\Scripts\activate # 本地安装(自动触发Meson编译Fortran代码) pip install . # 验证功能 python -c "import fortran2python; print(fortran2python.add(2, 3)); print(fortran2python.multiply(2.5, 4.0))"
6. 发布至PyPI
# 构建分发包 pip build . # 上传至PyPI(需提前安装twine并注册PyPI账号) pip install twine twine upload dist/*
内容的提问来源于stack exchange,提问作者Zaus
相关产品推荐
相关产品推荐

