Fortran调用C函数
时间:2022-07-22
本文章向大家介绍Fortran调用C函数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Fortran中调用C语言的函数这部分内容在彭国伦的教材中是有的,但那是基于Fortran 90标准,写法稍微有些烦琐。在Fortran 2003标准中有较为简洁的写法,本文通过几个简单的例子展示一下如何实现在Fortran中调C函数。
先上示例:
test.f90:
program main
implicit none
real(kind=4)::a,b,c
interface
subroutine calc(a,b,c) bind(c,name='calC')
use iso_c_binding
real(kind=c_float)::a,b,c
end subroutine calc
end interface
write(*,*) 'Enter a:'
read(*,*) a
write(*,*) 'Enter b:'
read(*,*) b
call calc(a,b,c)
write(*,*) "In Fortran: a+b= ",c
end
在这段Fortran代码中,尝试调用使用C语言编写的calc函数。对应的C语言的程序为:
test.c:
# include <stdio.h>
void calC(float *a, float *b, float *c)
{
*c = *a + *b;
printf(" In C: a + b = %fn", *c);
}
编译:
ifort -c test.f90 -o f.o
icc -c test.c -o c.o
ifort f.o c.o -o test.exe
运行生成的可执行文件test.exe,结果如下:
Enter a:
1
Enter b:
2
In C: a + b = 3.000000
In Fortran: a+b= 3.000000
解读:
1. 在Fortran程序中需要给C函数写一个interface,在subroutine XXX后面跟上bind(c, name='YYY')语句,表示XXX这个子程序链接的是C语言中的YYY函数。注意XXX和YYY这两个名字可以毫无关系,且是区分大小写的。本例中Fortran中的名字为calc,而C语言中为calC,两者也是不同的。如果两者名字相同,可以省略name='YYY'语句。
2. iso_c_binding模块中,实际上定义了诸如c_float这些变量的数值,如果你很清楚C语言和Fortran中各种变量的大小,也可以不使用iso_c_binding模块。本例中,c_float即为4,因此在interface中可以直接将变量声明为real(kind=4)。
以下再展示一例关于结构体和字符串的传递。
test2.f90
module data_types
use,intrinsic::iso_c_binding
implicit none
type,bind(c)::my_type
integer(kind=c_int)::n
real(kind=c_float)::data1
real(kind=c_float)::data2
end type my_type
end module data_types
program main
use,intrinsic::iso_c_binding
use data_types
type(my_type)::test_struct
character(kind=c_char),dimension(20)::c
interface
subroutine c_sub(my_struct,msg) bind(c)
use,intrinsic::iso_c_binding
use data_types
type(my_type)::my_struct
character(kind=c_char),dimension(20)::msg
end subroutine c_sub
end interface
test_struct%n=3
test_struct%data1=6.0
test_struct%data2=0.0
c(1)='H'; c(2)='e'; c(3)='l'; c(4)='l'; c(5)='o'; c(6)=c_null_char
write(*,*) 'Output before the call:'
write(*,*) 'test_struct%n=',test_struct%n
write(*,*) 'test_struct%data1=',test_struct%data1
write(*,*) 'test_struct%data2=',test_struct%data2
call c_sub(test_struct,c)
write(*,*) 'Output after the call:'
write(*,*) 'test_struct%n=',test_struct%n
write(*,*) 'test_struct%data1=',test_struct%data1
write(*,*) 'test_struct%data2=',test_struct%data2
end
test2.c
typedef struct {
int n;
float data1;
float data2;
} MyType;
void c_sub(MyType *my_struct, char c[])
{
my_struct->data2 = my_struct->n * my_struct-> data1;
printf(" String = %sn", c);
}
运行结果如下:
Output before the call:
test_struct%n= 3
test_struct%data1= 6.000000
test_struct%data2= 0.0000000E+00
String = Hello
Output after the call:
test_struct%n= 3
test_struct%data1= 6.000000
test_struct%data2= 18.00000
小编就不解读这段代码了,相信小伙伴们仔细看一下都会明白的。
参考资料:
Stephen J. Chapman, Fortran for Scientists and Engineers (4 ed).
- 关于Flashback的小测试(r10笔记第15天)
- 分享一个分布式消息总线,基于.NET Socket Tcp的发布-订阅框架,附代码下载
- 【Go 语言社区】Golang语言获取系统环境变量的方法
- Oracle中的PUBLIC(r10笔记第14天)
- Data Guard高级玩法:通过闪回恢复switchover主库 (r10笔记第13天)
- WinForm/MIS项目开发之中按钮级权限实践
- 恢复控制文件避免使用resetlogs选项 (r10笔记第12天)
- Go实现短url项目
- 【Go 语言社区】GO语言多核并行化的问题
- mysql执行计划看是否最优
- 通过IP定位区域的SQL优化思路(r10笔记第10天)
- Java基础-day06-知识点回顾与练习
- 【Go 语言社区】Golang语言的多核并行化例子
- 一条SQL语句的执行计划变化探究(r10笔记第9天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 设计模式~装饰模式
- Linux共享库、静态库、动态库详解
- strace详解及实战
- 推荐一个比crontab更好用的东西:crongo
- Vue 自定义指令
- IDEA + Spring Boot 的三种热加载方案,看完弄懂,不用加班~
- 开篇讲--关于Kali的碎碎念
- Mysql服务器SQL模式 (官方精译)
- 如何用Prometheus和Grafana监控Kubernetes集群?
- linux实时文件事件监听--inotify
- MySQL事务原理&实战【官方精译】
- 俗话:MySQL索引
- 基于飞桨复现CVPR 2016 MCNN的过程解析:教你更精确估算人流密度
- mysql各种引擎对比、实战
- 接球小游戏玩腻了?换个姿势让PaddleX帮你吊打游戏系统