接下来,介绍一个简单的例子,从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. Python --写excel

    # -*- coding: UTF-8 -*- import xlwt import StringIO # 将数据保存成excel def write_data(data, tname): file ...

  2. [android开发篇]自定义权限

    有时候,我们可能遇到如下需求场景:当用户在一个应用程序中进行某项操作时,会启动另外一个应用程序,最常见的时直接打开了另外一个应用程序,并进入其中某个Activity(如:有的应用中有推荐应用列表,当用 ...

  3. Tinkoff Challenge - Elimination Round 开始补题

    A. Oleg and shares time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  4. 九度oj 题目1352:和为S的两个数字

    题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k, ...

  5. cf3D Least Cost Bracket Sequence

    This is yet another problem on regular bracket sequences. A bracket sequence is called regular, if b ...

  6. LA 3135 优先队列

    题目大意:有若干命令,它有两个属性Q_Num,Period(周期).按时间循序模拟前k个命令并输出他们的Q_Num,若同时发生输出Q_Num最小的值. #include<iostream> ...

  7. LA 4728 旋转卡壳算法求凸包的最大直径

    #include<iostream> #include<cstdio> #include<cmath> #include<vector> #includ ...

  8. 美丽的大树(codevs 2124)

    题目描述 Description 平江路是苏州最美丽的道路,路中间的绿化带上种了两行漂亮的大树,每行50棵,一共100棵大树,这些大树被编上了号,编号方式如下: 1 3 5 7 ………… 45 47 ...

  9. flask-script插件

    首先在启动Flask项目时,我们可以传不同的参数作为运行参数.但是我们只能在入口app.run()传参.这样十分的不方便.Flask-Script 是一个 Flask 扩展,为 Flask 程序添加了 ...

  10. Laravel 5.1 报错:[App\Http\Requests\Request] is not instantiable

    Laravel 5.1 报错:[App\Http\Requests\Request] is not instantiable 错误提示: Whoops, looks like something we ...