Fortran和C++混合编程学习笔记
前言
学习中有Fortran和C++混合编程的需求,但参考《Fortran95程序设计》没有成功实现,最后在这里找到解决方案,特此记录几个demo。测试在windows环境中进行,使用的编译器有g++和gfortran。
一、integer求和
Fortran调用C++函数只需要在C++函数名后加下划线,然后在Fortran代码中像subroutine那样调用。需要注意的是Fortran传到C++函数的不是数值,所以要用指针接收。
Fortran代码fmix.f90:
program main
implicit none
integer ::a,b,c
a=1
b=2
call sum(a,b,c)
write(*,*) c
end program main
C++代码cmix.cpp:
extern "C"
{
void sum_(int *a, int *b, int *c)
{
*c = *a + *b;
}
}
makefile:
链接时存在需要添加-lstdc++参数的情况。
all:mix
cmix.o:cmix.cpp
g++ -c $^
fmix.o:fmix.f90
gfortran -c $^
mix:cmix.o fmix.o
gfortran -o $@ $^
运行结果:
代码将两个integer相加,并将结果输出。
二、一维数组求和
Fortran代码fmix.f90:
program main
implicit none
integer ::a(3) = (/1, 2, 3/)
integer ::b(3) = (/4, 5, 6/)
integer ::c(3)
integer ::i
call sum(a, b, c)
write (*, *) c
end program main
C++代码cmix.cpp:
extern "C"
{
void sum_(int *a, int *b, int *c)
{
for(int i=0;i<3;i++)
c[i]=b[i]+a[i];
}
}
makefile和之前一样。
运行结果:
代码将两个整型数组相加,并输出结果。
三、二维数组求和
Fortran代码fmix.f90:
program main
implicit none
integer ::a(2,2) = reshape((/1,2,3,4/),(/2,2/))
integer ::b(2,2) = reshape((/5,6,7,8/),(/2,2/))
integer ::c(2,2)
integer ::i
call sum(a, b, c)
write (*, *) c
end program main
C++代码cmix.cpp:
extern "C"
{
void sum_(int *a, int *b, int *c)
{
int stride = 2;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
c[stride * i + j] = a[stride * i + j] + b[stride * i + j];
}
}
}
}
makefile和之前一样。
运行结果:
目前没找到C++直接接受Fortran二维数组的方式,所以在C++代码中用一维数组模拟二维数组。注意Fotran数组在内存中为列优先排列,而C++数组为行优先排列。我在demo中没有体现这一点,实际工程代码可能需要注意。
总结
以上内容只是我在学习过程中对Fortran和C++混合编程的一个记录,并没有介绍太多Fortran和C++的内容,不足之处望谅解。后续可能会更新遇到的各种Fortran和其他语言混编问题吧。。。