在C中使用Fortran代码

我尝试在C中使用fortran例程,但我不工作。 我不知道我犯了什么错误。 这里是我的Fortran代码,包括我想在C中使用的Integration-Module:

module integration implicit none contains function Integrate(func, a,b, intsteps) result(integral) interface real function func(x) real, intent(in) :: x end function func end interface real :: integral, a, b integer :: intsteps intent(in) :: a, b, intsteps optional :: intsteps real :: x, dx integer :: i,n integer, parameter :: rk = kind(x) n = 1000 if (present(intsteps)) n = intsteps dx = (ba)/n integral = 0.0_rk do i = 1,n x = a + (1.0_rk * i - 0.5_rk) * dx integral = integral + func(x) end do integral = integral * dx end function end module integration real(c_float) function wrapper_integrate(func,a,b, intsteps) result(integral) bind(C, name='integrate') use iso_c_binding use integration interface real(c_float) function func(x) bind(C) use, intrinsic :: iso_c_binding real(c_float), intent(in) :: x end function func end interface real(c_float) :: a,b integer(c_int),intent(in) :: intsteps optional :: intsteps if (present(intsteps)) then integral = Integrate(func,a,b,intsteps) else integral = Integrate(func,a,b) endif end function wrapper_integrate 

和我的C代码:

 #include  #include  float sin2(float x) { return sin(x) * sin(x); } float integrate(float(*func)(float), float a, float b, int intsteps); int main() { float integral; integral = integrate(sin2,0.,1.,10000); printf("%f",integral); return 0; } 

如果我执行

 g++ -c main.c gfortran -c integration.f95 g++ main.o integration.o 

我明白了

 undefined reference to `integrate(float (*)(float), float, float, int)' 

有谁知道如何处理这个?

如果使用模块ISO_C_Binding ,则可以直接将函数从C传递给Fortran作为函数指针C_FUNPTR 。 详情请见此处 。

在您的情况下,这将看起来像:

 real(c_float) function wrapper_integrate(func, a, b, intsteps) result(integral) bind(C, name='integrate') use iso_c_binding use integration abstract interface function iFunc(x) bind(C) use, intrinsic :: iso_c_binding real(c_float) :: iFunc real(c_float), intent(in) :: x end function iFunc end interface type(C_FUNPTR), INTENT(IN), VALUE :: func real(c_float) :: a,b integer(c_int),intent(in) :: intsteps optional :: intsteps procedure(iFunc),pointer :: myfunc call c_f_procpointer(func, myfunc) if (present(intsteps)) then integral = Integrate(myfunc,a,b,intsteps) else integral = Integrate(myfunc,a,b) endif end function wrapper_integrate 

显然,你的解决方案更优雅;-)

另请注意,Fortran通过引用传递变量(除非您指定VALUE属性,否则不会)。 因此,您需要相应地更改C代码:

 #include  #include  float sin2(float *x) { return sin(*x) * sin(*x); } float integrate(float(*func)(float*), float* a, float* b, int* intsteps); int main() { float integral; float a=0.; float b=1.; int intsteps=10000; integral = integrate(sin2, &a, &b, &intsteps); printf("%f",integral); return 0; } 

您正在使用C ++编译器,而不是C编译器。 链接约定可能不同。

你忘了链接数学库(因为

 gcc -c main.c gfortran -c integration.f95 gcc main.o integration.o -lm