接下来,介绍一个简单的例子,从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混合的动态链接库--中篇的更多相关文章

  1. Python调用C/Fortran混合的动态链接库--上篇

    内容描述: 在32位或64位的windows或GNU/Linux系统下利用Python的ctypes和numpy模块调用C/Fortran混合编程的有限元数值计算程序 操作系统及编译环境: 32bit ...

  2. Python调用C/Fortran混合的动态链接库-下篇

    接着前面的内容,我们在这里继续介绍Python传递二维数组到fortran并进行简单计算后返回的例子. 问题描述: module py2f90 use,intrinsic::iso_c_binding ...

  3. Python调用C的DLL(动态链接库)

    开发环境:mingw64位,python3.6 64位 参考博客: mingw编译dll: https://blog.csdn.net/liyuanbhu/article/details/426123 ...

  4. Python调用DLL动态链接库——ctypes使用

    最近要使用python调用C++编译生成的DLL动态链接库,因此学习了一下ctypes库的基本使用. ctypes是一个用于Python的外部函数库,它提供C兼容的数据类型,并允许在DLL或共享库中调 ...

  5. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  6. Python调用C/C++动态链接库

    Python调用C/C++动态链接库 2013年07月26日 ⁄ 综合 ⁄ 共 3219字 ⁄ 字号 小 中 大 ⁄ 评论关闭   吐槽(可略过):不知不觉,4月份毕业,5月份进入团队,已有7个月.大 ...

  7. Python调用C/C++动态链接库的方法详解

    Python调用C/C++动态链接库的方法详解 投稿:shichen2014 这篇文章主要介绍了Python调用C/C++动态链接库的方法,需要的朋友可以参考下 本文以实例讲解了Python调用C/C ...

  8. Python的扩展接口[2] -> 动态链接库DLL[1] -> 组件对象模型 COM 的 Python 调用

    组件对象模型 COM 的 Python 调用 关于COM的基本概念,可参考组件对象模型 COM的内容,下面主要介绍两种使用 Python 调用 COM 组件的方法. 1 使用 win32com 1.1 ...

  9. python调用C/C++动态链接库和jython

    总结(非原创) Python调用C库比较简单,不经过任何封装打包成so,再使用python的ctypes调用即可. 1. C语言文件:pycall.c #include <stdio.h> ...

随机推荐

  1. vim 第三章 插入模式

    vim 第三章  插入模式 在普通模式下可以删除  复制   及粘贴的命令    在插入模式下也存在以中方便快捷的方式    能够粘贴寄存器中文本   两种方式来插入键盘上不存在的非常用字符 替换模式 ...

  2. python--getitem一拦截索引运算

    getitem一拦截索引运算 __getitem__方法拦截实例的索引运算.当实例x出现在x[i]这样的索引运算中时,Python会调用这个实例继承的__getitem__方法(如果有的话),把x作为 ...

  3. Caffe 不同版本之间layer移植方法

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/52185521 (前两天这篇博客不小心被 ...

  4. Cookie窃取实验

    文章:IE/FIREFOX/CHROME等浏览器保存COOKIE的位置 Chrome的Cookie数据位于:%LOCALAPPDATA%\Google\Chrome\User Data\Default ...

  5. 九度oj 题目1111:单词替换

    题目描述: 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写.现需要将其中的某个单词替换成另一个单词,并输出替换之后的字符 ...

  6. Codeforces Round #354 (Div. 2)——C. Vasya and String(尺取)

    C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. BZOJ 2882 工艺 ——后缀自动机 最小表示法

    先说后缀自动机的做法. 直接把S串复制一遍成SS,然后建立后缀自动机,go边相当于在当前字符的后面插入,而son边可以看作在字符串前面加一个字符. 所以贪心的走字典序最小的边即可,而且根据后缀自动机的 ...

  8. 【FFT求卷积】Problem D. Duel

    [AC] #include <stdio.h> #include <iostream> #include <string.h> #include <algor ...

  9. CI(CodeIgniter)框架中的增删改查操作

    我们创建一个模型( 项目目录/models/),请注意:模型名与文件名相同且必须继承数据核心类CI_Model,同时重载父类中的构造方法 CodeIgniter的数据函数类在 \models\User ...

  10. 洛谷 [P2575] 高手过招

    SG函数+状压记忆化搜索 观察题目发现,每一行都是独立的,只要处理出来每一行的SG值,异或起来就好 每一行的SG值可以用状压+记忆化搜索的方法来求,对位运算技术是个很大的考验 注意SG值要预处理出来, ...