Use Fortran-code in C

天涯浪子 提交于 2019-12-06 04:23:14

If you are using the module ISO_C_Binding, you can directly passing a function from C to Fortran as a function pointer C_FUNPTR. See here for details.

In your case, this would look like:

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

Obviously, your solution is more elegant ;-)

Also, please note that Fortran passes variables by reference (unless you specify the VALUE attribute, which you don't). Therefore, you need to change you C code accordingly:

#include <stdio.h>
#include <math.h>

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;
}

You are using the C++ compiler, not the C one. Linking conventions may be different.

And you forgot to link with the math library (because of sin)

gcc -c main.c
gfortran -c integration.f95
gcc main.o integration.o  -lm
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!