Fortran-C 互操作性基本示例

Fortran-C interoperativity basic example

我正在尝试学习如何从 C 程序调用 Fortran 函数或子例程,我做了这个简单的例子:

Fortran函数区.f90为

function Area_Circle(r)

implicit none

real(kind(1.d0)) , intent(out):: Area_Circle
real(kind(1.d0)), intent(in) :: r

real(kind(1.d0)), parameter :: Pi = acos(-1.d0)

Area_Circle = Pi * r * r

end function Area_Circle

和 C main.c 程序

#include <stdio.h>

extern double Area_Circle_(double *r);

int main(int argc, char **argv){
    double r;

    printf("Enter the radius\n");
    scanf("%lf", &r);

    printf("The area is %lf\n", Area_Circle_(&r));

    return 0;
}

我尝试使用命令编译构建

gcc -o app main.c area.f90 -lgfortran

出口是

area.f90:1:0:

 function Area_Circle(r)
 
Error: Symbol at (1) is not a DUMMY variable

我应该怎么做才能正确编译并运行?

P.D.: 我通常不使用 Fortran,但我的一些同事是的。为此,我想学习 Fortran-C 互操作性。

有很多事情需要解决。

您的 Fortran 函数 Area_Circle 不正确:函数名称的类型也就是它的 return 类型不能有 intent.

Fortran 标准中定义了一个模块,它使 Fortran-C 的互操作性定义明确且可移植:iso_c_binding。你应该利用它,例如注意 bind(c) 属性和真实种类 c_double.

Fortran 不区分大小写 s.t。您需要在您的 C 程序中以全小写形式调用它,即 area_circle 而不是 Area_Circle_。 可以使用 bind(c, name="<some_name>").

覆盖此行为

Fortran 文件 area.f90

function Area_Circle(r) bind(c)
  use, intrinsic :: iso_c_binding
  implicit none

  real(c_double), intent(in) :: r
  real(c_double)             :: Area_Circle

  real(c_double), parameter :: PI = acos(-1.d0)

  Area_Circle = PI * r * r
end function

C文件main.c

#include <stdio.h>

extern double area_circle(double *r);

int main(int argc, char **argv){
    double r;

    printf("Enter the radius\n");
    scanf("%lf", &r);

    printf("The area is %lf\n", area_circle(&r));

    return 0;
}