利用numpy中的ctypeslib和python基础库ctypes调用fortran
2022/1/14 17:06:32
本文主要是介绍利用numpy中的ctypeslib和python基础库ctypes调用fortran,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
1、ubuntu18.04环境
2、win10环境
3、参考文章
上篇文章windows下python利用f2py调用Fortran我记录了利用numpy中的f2py调用fortran的方法,本文再介绍下在windows环境下,利用ctypeslib和ctypes调用fortran所踩过的坑。
基本的环境搭建参考上篇文章,这里就不再赘述,即安装好mingw-w64编译环境。
参考了博客园pasuka大神的文章Python调用C/Fortran混合的动态链接库-下篇,在ubuntu18.04环境下测试成功,但在windows下编译能成功,调用时却出了问题!
1、ubuntu18.04环境
ctypes2d_array_test.f90
module py2f90 use,intrinsic::iso_c_binding implicit none contains subroutine transferMat2For(matrix,n1,n2)bind(c,name='array2py') implicit none integer(c_int),intent(in),value::n1,n2 real(c_float),intent(out)::matrix(n1,n2) integer::i,j ! initialize matrix matrix = 0.0E0 ! loop do i=1,n1 do j=1,n2 matrix(i,j) = real(i,4)*1.E1+real(j,4)*2.E0 write(*,"('Row:',i4,1x,'Col:',i4,1x,'Value:',1x,F5.2)")i,j,matrix(i,j) enddo enddo return end subroutine end module program test use py2f90 implicit none real(kind=4)::aa(4,5) call transferMat2For(aa,4,5) end program
py2f90_test.py
#! /usr/bin/env python #coding=utf-8 import numpy as np from numpy.ctypeslib import load_library,ndpointer from ctypes import c_int # shape of 2d array n1,n2 = 2,4+1 # create an empty 2d array data = np.empty(shape=(n1,n2),dtype='f4',order='f') flib = load_library("test","./") flib.argtypes = [ndpointer(dtype='f4',ndim=2),c_int,c_int] flib.array2py(data.ctypes.data,n1,n2) print("*"*80) print(data)
用gfortran编译:
gfortran ctypes2d_array_test.f90 -fPIC -shared -o test.so
在ubuntu下运行正常:
2、win10环境
在win10环境下,编译指令:
gfortran py2f90.f90 -fPIC -shared -g -o test_mat.dll -fno-underscoring
编译能成功,但调用时出错:
错误定位到了第14行,flib.array2py(data.ctypes.data, n1, n2)这句,提示int too long to convert
但明明python3中,int是没有大小上限的,那为啥还会出现溢出错误呢?原因是fortran里的整数类型会出现溢出,其实我们的目的只是想把data这个numpy数组的首地址传递到fortran编写的array2py函数,这时可以用到ndarray.ctypes.data_as方法替换ndarray.ctypes.data属性,将py2f90_test.py代码做一些更改如下:
#coding=utf-8 from sys import flags import numpy as np from numpy.ctypeslib import load_library,ndpointer from ctypes import c_int,POINTER,c_float # shape of 2d array n1,n2 = 2,4+1 # create an empty 2d array data = np.empty(shape=(n1,n2),dtype='f4',order='f') flib = load_library("test","./") # flib.argtypes = [ndpointer(dtype='f4',ndim=2),c_int,c_int] flib.argtypes = [POINTER(c_float),c_int,c_int] print(data.ctypes.data_as(POINTER(c_float))) print(data.ctypes.data) flib.array2py(data.ctypes.data_as(POINTER(c_float)),n1,n2) # flib.array2py(data.ctypes.data,n1,n2) print("*"*80) print(data)
运行结果如下:
可见用ndarray.ctypes.data_as方法比用ndarray.ctypes.data属性代码健壮性更好,既可以在linux下运行,也能在windows下运行,另外ndpointer和POINTER对代码的运行没什么影响,但ndpointer使用起来更灵活,因为既可以指定数组的返回值类型,也可以指定维度,更方便代码理解。
3、参考文章
Python调用C/Fortran混合的动态链接库-下篇https://www.cnblogs.com/pasuka/p/4012508.html
Python使用ctypes模块调用DLL函数之C语言数组与numpy数组传递https://baijiahao.baidu.com/s?id=1615404760897105428&wfr=spider&for=pc
这篇关于利用numpy中的ctypeslib和python基础库ctypes调用fortran的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-25Python编程基础:变量与类型
- 2024-11-25Python编程基础与实践
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器