问题描述
我正在尝试学习如何从 C 程序调用 Fortran 函数或子例程,我做了这个简单的例子:
Fortran 函数 area.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
不正确:函数名称的类型(即其返回类型)不能包含 intent
。
Fortran 标准中定义了一个模块,它使 Fortran-C 的互操作性定义明确且可移植:iso_c_binding
。你应该利用它,例如注意 bind(c)
属性和真正的种类 c_double
。
Fortran 不区分大小写。您需要在 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;
}