Python调用C/Fortran混合的动态链接库--中篇
接下来,介绍一个简单的例子,从fortran中传递并返回一维自定义结构体数组到python
注意点:
1、fortran新标准支持可分配数组作为变量传入并在subroutine或function分配后返回;
2、BIND不支持传入可分配数组(也即1和2无法同时使用);
3、fortran没有垃圾自动回收机制;
综合上述3点,利用ctypes调用fortran不能也不宜直接返回形状大小在计算前无法确定的数组,折衷的办法是:
a、估算出返回数组的大小,可以适当偏大;
b、在fortran的module定义全局可分配数组,第一次调用后存储结果并返回数组形状数值,在python中利用numpy开辟空数组,再次调用fortran得到结果并清空fortran中module的全局变量
fortran代码:
module sam
use,intrinsic::iso_c_binding
implicit none
type,bind(C)::abc
!Define struct
character(len=)::nam
real(c_float)::val()
end type
! Global variable in fortran module
! Notice: dealloacte after using to avoid memory leak
type(abc),allocatable::stu(:)
contains
subroutine calc(input,output,n1)bind(c,name='ex01')
! Example
! Both in and out variables has assumed shape
! Bind(C) not allowed pass alloctable variables
! Pure Fortran2008 allows pass alloctable array to subroutine to allocate or deallocate
implicit none
integer(c_int),intent(in),value::n1
real(c_float),intent(in)::input(n1)
type(abc),intent(out)::output(*n1) integer::i do i=,size(output)
output(i)%nam = "abcdefea"
output(i)%val(:) = real(i-,)
output(i)%val(::) = i*2.5E0
enddo
return
end subroutine subroutine calc2(input,n1,n2)bind(c,name='ex02_1')
! Example 02_1
! Return result's shape
implicit none
integer(c_int),intent(in),value::n1
real(c_float),intent(in)::input(n1)
integer(c_int),intent(out)::n2 integer::i,j call clear()
if(input()<.E0)then
allocate(stu())
else
allocate(stu(int(input())+))
endif
do i=,size(stu)
stu(i)%nam = "daefvdefefadfad"
do j=,size(stu(i)%val)
stu(i)%val(j) = i*j*1.5E0
enddo
enddo
n2 = size(stu)
return
end subroutine subroutine getdata(output,n)bind(c,name='ex02_2')
! Example 02_2
! Return result and do clear
implicit none
integer(c_int),intent(in),value::n
type(abc),intent(out)::output(n) output = stu
call clear()
return
end subroutine subroutine clear()
implicit none
if(allocated(stu))deallocate(stu)
end subroutine
end module program test
use sam
implicit none
real(c_float)::array()
type(abc)::student(*)
integer::i array = [.E0,.E0,.E0,.E0,.E0]
call calc(array,student,)
do i=,size(student)
write(*,*)student(i)%nam,student(i)%val
enddo
end program
python代码:
#! /usr/bin/env python
#coding=utf-8 '''
A short example of use ctypes and numpy to call fortran dynamic library
example for 1d struct array pass or access
'''
import numpy as np
from numpy.ctypeslib import load_library,ndpointer
from ctypes import c_int #define struct as same sa fortran
abc = np.dtype([("nam",'S80',1),("val",'f4',10)])
#load dynamic library
flib = load_library("libexample",".")
#function handle of ex01
fun01 = flib.ex01
#define input arguments
fun01.argtypes = [ndpointer('f4'),ndpointer(abc),c_int]
#
n1,n2 = 5,np.array(0,'i4')
vec = np.zeros((n1,),'f4')
student = np.empty((n1*2,),abc)
#print vec
fun01(vec,student,n1)
#print student
#function handle of ex02_1
fun02_1 = flib.ex02_1
fun02_1.argtypes = [ndpointer('f4'),c_int,ndpointer('i4')]
fun02_1(vec,n1,n2)
#print n1,n2
#function handle of ex02_2
fun02_2 = flib.ex02_2
fun02_2.argtypes = [ndpointer(abc),c_int]
student2 = np.empty((n2,),abc)
fun02_2(student2,n2)
print student2
编译命令:
gfortran test.f90 -fPIC -shared -o libexample.so
Python调用C/Fortran混合的动态链接库--中篇的更多相关文章
- Python调用C/Fortran混合的动态链接库--上篇
内容描述: 在32位或64位的windows或GNU/Linux系统下利用Python的ctypes和numpy模块调用C/Fortran混合编程的有限元数值计算程序 操作系统及编译环境: 32bit ...
- Python调用C/Fortran混合的动态链接库-下篇
接着前面的内容,我们在这里继续介绍Python传递二维数组到fortran并进行简单计算后返回的例子. 问题描述: module py2f90 use,intrinsic::iso_c_binding ...
- Python调用C的DLL(动态链接库)
开发环境:mingw64位,python3.6 64位 参考博客: mingw编译dll: https://blog.csdn.net/liyuanbhu/article/details/426123 ...
- Python调用DLL动态链接库——ctypes使用
最近要使用python调用C++编译生成的DLL动态链接库,因此学习了一下ctypes库的基本使用. ctypes是一个用于Python的外部函数库,它提供C兼容的数据类型,并允许在DLL或共享库中调 ...
- [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库
前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...
- Python调用C/C++动态链接库
Python调用C/C++动态链接库 2013年07月26日 ⁄ 综合 ⁄ 共 3219字 ⁄ 字号 小 中 大 ⁄ 评论关闭 吐槽(可略过):不知不觉,4月份毕业,5月份进入团队,已有7个月.大 ...
- Python调用C/C++动态链接库的方法详解
Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...
- Python的扩展接口[2] -> 动态链接库DLL[1] -> 组件对象模型 COM 的 Python 调用
组件对象模型 COM 的 Python 调用 关于COM的基本概念,可参考组件对象模型 COM的内容,下面主要介绍两种使用 Python 调用 COM 组件的方法. 1 使用 win32com 1.1 ...
- python调用C/C++动态链接库和jython
总结(非原创) Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可. 1. C语言文件:pycall.c #include <stdio.h> ...
随机推荐
- 如何诊断RAC系统中的'gc cr multi block request'?
'gc cr multi block request' 是RAC数据库上比较常见的一种等待事件,在RAC 上进行全表扫描(Full Table Scan)或者全索引扫描(Index Fast Full ...
- 【Luogu】P3708Koishi的数字游戏(数论)
题目链接 考虑f(i)=i%1+i%2+i%3+.....+i%n f(i+1)=(i+1)%1+(i+1)%2+......+(i+1)%n 其中不是i+1的因数的部分在f(i+1)的地方都加了1. ...
- HDU——2955Robberies(小数背包)
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 洛谷 [P1995] 程序自动分析
并查集+ 离散化 首先本题的数据范围很大,需要离散化, STL离散化代码: //dat是原数据,id是编号,sub是数据的副本 sort(sub + 1, sub + tot + 1); size = ...
- MySql将查询结果插入到另外一张表
今天遇到一个业务需求是这样的:对在职员工超过55岁提醒.我想的思路是查询员工表,然后将超过55岁的人的信息存到另一个表,并且以消息的形式给用户提示,用户处理掉之后此消息失效(在数据库做标记). 不管是 ...
- AnyChart创建实时仪表
AnyChart创建实时仪表 简述: AnyChart是一款基于Flash和HTML5的图表.仪表控件,所包含的图表类型众多和跨平台以及跨浏览器是该产品的主要特点和优点,另外该产品基于XML文件作为数 ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
- 由String作为方法参数,引起的值传递,引用传递,及StringBuffer
原文引用: http://www.cnblogs.com/zuoxiaolong/p/lang1.html http://www.cnblogs.com/clara/archive/2011/09/1 ...
- 解决 Mac OS X Retina 屏幕显示环境下 jEdit 字体模糊的方法
Mac OS X Retina 屏幕显示环境下,字体非常清晰.但是 jEdit 仍然很模糊,虽然 jEdit 用的是 Java,但这并不是理由.因为诸如 NetBeans 以及 IntelliJ ID ...
- 转:Linux字符编码方式
首先,解释一下字符集: 汉字编码: * GB2312字集是简体字集,全称为GB2312(80)字集,共包括国标简体汉字6763个. * BIG5字集是台湾繁体字集,共包括国标繁体汉字13053个. * ...