Mix C Fortran:修订间差异

来自Ubuntu中文
跳到导航跳到搜索
Dbzhang800留言 | 贡献
Dbzhang800留言 | 贡献
 
(未显示同一用户的4个中间版本)
第21行: 第21行:


下面的 Fortran 程序调用一个 C 函数,函数传递的参数是一个字符串和一个浮点数:
下面的 Fortran 程序调用一个 C 函数,函数传递的参数是一个字符串和一个浮点数:
C  fortran2c.f
<source lang="fortran">
C
C  fortran2c.f
        PROGRAM FORTRAN2C
C
C
        PROGRAM FORTRAN2C
        CHARACTER*32 HELLO
C
        REAL PI
        CHARACTER*32 HELLO
C
        REAL PI
        HELLO = "Hello C from Fortran"
C
        HELLO(21:21) = CHAR(0)
        HELLO = "Hello C from Fortran"
        PI = 3.14159
        HELLO(21:21) = CHAR(0)
        CALL SHOWHIPI(HELLO,PI)
        PI = 3.14159
        END PROGRAM FORTRAN2C
        CALL SHOWHIPI(HELLO,PI)
        END PROGRAM FORTRAN2C
</source>


其中,可存储32个字符的 CHARACTER 型字符串变量 HELLO 中,存有 21 个字符,剩余部分用空格填充。要将该字符串格式化为 C 语言标准的字符串,我们必须在实际字符串结束的位置插入一个 ascii 码为“0”字符作为结束标志。而 REAL 型浮点数 PI 存储方式和 C 中 float 型变量完全一样,因此可以直接传递给函数。
其中,可存储32个字符的 CHARACTER 型字符串变量 HELLO 中,存有 21 个字符,剩余部分用空格填充。要将该字符串格式化为 C 语言标准的字符串,我们必须在实际字符串结束的位置插入一个 ascii 码为“0”字符作为结束标志。而 REAL 型浮点数 PI 存储方式和 C 中 float 型变量完全一样,因此可以直接传递给函数。


理解 Fortran 的参数总是通过引用传递是非常重要的,因此 C 函数接收到的总是被传递的变量的地址而不是变量值本身。下面的 C 函数输出 Fortran 程序传递进来的字符串和和浮点数:
理解 Fortran 的参数总是通过引用传递是非常重要的,因此 C 函数接收到的总是被传递的变量的地址而不是变量值本身。下面的 C 函数输出 Fortran 程序传递进来的字符串和和浮点数:
/* showhipi.c */
<source lang="c">
#include <stdio.h>
/* showhipi.c */
void showhipi_(char *string,float *pi)
#include <stdio.h>
{
void showhipi_(char *string,float *pi)
        printf("%s\nPI=%f\n",string,*pi);
{
}
      printf("%s\nPI=%f\n",string,*pi);
}
</source>


在不同的平台下 Fortran 和 C 语言的命名惯例和数据类型的匹配关系是不同的。如同你在本例中看到的,在函数名后添加一下划线是必须的。
在不同的平台下 Fortran 和 C 语言的命名惯例和数据类型的匹配关系是不同的。如同你在本例中看到的,在函数名后添加一下划线是必须的。
第56行: 第60行:


==C调用Fortran函数==
==C调用Fortran函数==
要在 C 中调用一个 Fortran 子程序,我们必须传递参数的地址并将字符串格式化为 Fortran 的格式。在下面的例子的,我们给 Fortran 子程序传递了一个字符串和一个浮点数:
<source lang="c">
/* c2fortran.c */
int main(int argc,char *argv[])
{
    int i;
    float e = 2.71828;
    char hello[32];
    int length = sizeof(hello);
    strcpy(hello,"Hello Fortran from C");
    for(i=strlen(hello); i<length; i++)
          hello[i] = ' ';
    showhie_(hello,&length,&e);
    return(0);
}
</source>
                   
在 C 中,字符串的长度是由 null 字符的位置决定的,但在 Fortran 中,所有字符串的长度都是固定的。由于 Fortran 没有办法确定传递给它字符串的长度,我们必须将字符串长度作为参数同时传递。
本例中,字符数组用空格填充,数组大小作为第二个参数传递。注意到三个参数都是通过指针传递的──因为 Fortran 总是期待地址而不是真实的值。在被调用的子程序名后添加一下划线通常是必须的。
下面是被调用的 Fortran 子程序的源代码:
<source lang="fortran">
C  showhie.f
C
        SUBROUTINE SHOWHIE(HELLO,LENGTH,E)
        CHARACTER*(*) HELLO
        INTEGER LENGTH
        REAL E
C
        WRITE(*,100) HELLO(1:LENGTH),LENGTH,E
    100 FORMAT(3X,A,2X,I3,4X,F6.4)
        RETURN
        END SUBROUTINE SHOWHIE
</source>
下面的三条命令编译源文件并链接成一个可执行文件:
$ gfortran -c showhie.f -o showhie.o
$ gcc -c c2fortran.c -o c2fortran.o
$ gfortran c2fortran.o showhie.o -o c2fortran


==其他参考==
==其他参考==
{{Gccmorerefer}}
{{Gccmorerefer}}

2008年6月13日 (五) 21:50的最新版本

Fortran与C混合编程

由于 GNU 的 Fortran 和 C 语言二者的函数彼此可以直接相互调用,所以混合编程可以非常容易地实现。只要你足够仔细,确保函数调用时传递的参数类型正确,函数就可以在两种语言间来回调用,就像它们是同一种语言一样。

下表中列出了 Fortran 的数据类型和它们在 C 中对应的类型。这张表在大多数平台下是没问题的,但是或许会有例外的情况发生。在你打算传递某种数据类型时,先编写一个简单的例子进行测试将是很明智的。

C 类型Fortran 类型描述
signed charINTEGER*18位有符号整数
shortINTEGER*216位有符号整数
intINTEGER32位有符号整数
floatREAL32位浮点数
doubleDOUBLE PRECISION64位浮点数
void sub_()SUBROUTINE SUB()无返回值的 C 函数等价于 Fortran 子程序
float fun_()REAL FUNCTION FUN()有返回值的 C 函数等价于 Fortran 的函数


由于 Fortran 总是以引用的方式传递参数,而 C 则始终以地址方式传递数组,因此数组做参数时不需做任何修改。但是对多维数组来说,混合调用时其下标需要翻转,因为 Fortran 的数组是以列为主序(column-major order)而 C 数组以行为主序(row-major order)。

Fortran调用C函数

下面的 Fortran 程序调用一个 C 函数,函数传递的参数是一个字符串和一个浮点数: <source lang="fortran"> C fortran2c.f C

       PROGRAM FORTRAN2C

C

       CHARACTER*32 HELLO
       REAL PI

C

       HELLO = "Hello C from Fortran"
       HELLO(21:21) = CHAR(0)
       PI = 3.14159
       CALL SHOWHIPI(HELLO,PI)
       END PROGRAM FORTRAN2C

</source>

其中,可存储32个字符的 CHARACTER 型字符串变量 HELLO 中,存有 21 个字符,剩余部分用空格填充。要将该字符串格式化为 C 语言标准的字符串,我们必须在实际字符串结束的位置插入一个 ascii 码为“0”字符作为结束标志。而 REAL 型浮点数 PI 存储方式和 C 中 float 型变量完全一样,因此可以直接传递给函数。

理解 Fortran 的参数总是通过引用传递是非常重要的,因此 C 函数接收到的总是被传递的变量的地址而不是变量值本身。下面的 C 函数输出 Fortran 程序传递进来的字符串和和浮点数: <source lang="c"> /* showhipi.c */

  1. include <stdio.h>

void showhipi_(char *string,float *pi) {

      printf("%s\nPI=%f\n",string,*pi);

} </source>

在不同的平台下 Fortran 和 C 语言的命名惯例和数据类型的匹配关系是不同的。如同你在本例中看到的,在函数名后添加一下划线是必须的。

下面的命令编译两个源文件并将其链接成一个可执行程序:

$ gfortran -c fortran2c.f -o fortran2c.o
$ gcc -c showhipi.c -o showhipi.o
$ gfortran fortran2c.o showhipi.o -o fortran2c

最后一条命令也可用

$ gcc fortran2c.o showhipi.o -o fortran2c -lgfortranbegin -lgfortran

C调用Fortran函数

要在 C 中调用一个 Fortran 子程序,我们必须传递参数的地址并将字符串格式化为 Fortran 的格式。在下面的例子的,我们给 Fortran 子程序传递了一个字符串和一个浮点数: <source lang="c"> /* c2fortran.c */ int main(int argc,char *argv[]) {

    int i;
    float e = 2.71828;
    char hello[32];
    int length = sizeof(hello);
    strcpy(hello,"Hello Fortran from C");
    for(i=strlen(hello); i<length; i++)
         hello[i] = ' ';
    showhie_(hello,&length,&e);
    return(0);

} </source>

在 C 中,字符串的长度是由 null 字符的位置决定的,但在 Fortran 中,所有字符串的长度都是固定的。由于 Fortran 没有办法确定传递给它字符串的长度,我们必须将字符串长度作为参数同时传递。

本例中,字符数组用空格填充,数组大小作为第二个参数传递。注意到三个参数都是通过指针传递的──因为 Fortran 总是期待地址而不是真实的值。在被调用的子程序名后添加一下划线通常是必须的。

下面是被调用的 Fortran 子程序的源代码: <source lang="fortran"> C showhie.f C

       SUBROUTINE SHOWHIE(HELLO,LENGTH,E)
       CHARACTER*(*) HELLO
       INTEGER LENGTH
       REAL E

C

       WRITE(*,100) HELLO(1:LENGTH),LENGTH,E
   100 FORMAT(3X,A,2X,I3,4X,F6.4)
       RETURN
       END SUBROUTINE SHOWHIE

</source>

下面的三条命令编译源文件并链接成一个可执行文件:

$ gfortran -c showhie.f -o showhie.o
$ gcc -c c2fortran.c -o c2fortran.o
$ gfortran c2fortran.o showhie.o -o c2fortran

其他参考