Fortran调用C++
在Fortran中我们偶尔会去调用已经用C++写好的代码,要实现这个功能就需要写好接口程序,开发人员已经将接口抽象出来,也就意味着我们不需要在汇编的级别进行编写。今天讲的是Fortran调用C++,调用C语言接口会有些不同,今天不讲关于调用C语言的内容。
Fortran中有很多内建函数和内建模块可供使用,一部分是为了解决各种版本的编译器之间的兼容问题,例如iso_fortran_env模块中包含了各种数据类型的kind信息,gfortran中定义双精度浮点型变量是通过real(8)实现的,但是有些编译器这里的数字不一定是8。在模块iso_fortran_env中有一些常量可以避免这些问题,例如real64,定义双精度浮点数的时候就可以利用real(real64)来进行声明,也就是不用管那个括号里应该是什么。另一个模块iso_c_binding里含有的就是Fortran和C++交互的信息。
例子:
由于是Fortran和C++交互,从而有两段代码。
File: sub.cpp
1 | 1 |
File: main.f95
1 | 1 module func |
这里先简单说明一下Cpp文件中的内容,其中double对应于real(8),都是双精度浮点型,有返回值的对应function,无返回值(void)的对应subroutine。这里我定义了三个函数,分别是求模、求算数平方根和Hello World!的函数。
首先一个C++函数若要能被Fortran调用,首先要将函数声明到external中,这个操作是在Cpp文件中进行的。另外需要在Fortran中声明接口,这里的参数类型一定要一一对应,另外我在前面提到过,Fortran中传递变量都是默认传址的,所以在Cpp当中的变量都必须是指针类型(C++数组就是通过指针访问的)。在Fortran文件中定义interface时需要额外加上bind(C)语句,用于声明这是C++的接口程序,并且要提前导入iso_c_binding模块。另外需要注意的是Fortran中数组是列优先,而C/C++中是行优先,在传递一维数组的时候不会有问题,但是传递二维数组的时候要记着颠倒维度顺序。
下面我列出编译指令,一共有两种方式进行编译,不过本质是一样的。
File: test.sh
1 | gfortran -c main.f95 -o main.o |
其中g++是GNU的C++编译器。最后两条指令,随便哪条都行。g++编译器若要链接Fortran则需要调用lgfortran库,同理gfortran要链接C++则需要调用lstdc++库。