ISO_C_BINDING C function call from Fortran (with doubles and arrays)

I posted a similar question a few weeks ago ( iso_c_binding calling a C procedure with pointers from Fortran with arrays ) and I found a solution to my problem. Now I have changed a few things and am having trouble again. The following is a simplified version of my problem.

I have a main program in fortran:

program main_dummy ! compile: gcc -c dummy_trace.c ! f95 raytracing.f90 main_dummy.f90 dummy_trace.o -o main use, intrinsic :: ISO_C_BINDING use raytracing implicit none !real(kind=8) :: x_in(4), x_fin(4) real(C_DOUBLE), dimension(0:3) :: x_in, x_fin real(C_DOUBLE) :: spin integer :: rt_ok x_in = (/1,2,3,4/) x_fin = (/0,0,0,0/) spin = 0.7 write(*,*)'x_in, x_fin before = ', x_in, x_fin rt_ok = photon_trace(spin,x_in,x_fin) write(*,*)'return rt = ', rt_ok write(*,*)'x_in, x_fin after = ', x_in, x_fin end program main_dummy 

Why use a subroutine containing an interface for subroutine C:

 module raytracing Interface integer (C_INT) function photon_trace(BHsp, x_init, x_final) & bind(C, name='photon_trace') use , intrinsic :: ISO_C_BINDING implicit none real(C_DOUBLE) :: BHsp, x_init(4), x_final(4) end function photon_trace end interface end module raytracing 

and this is the C routine:

 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> #undef I int photon_trace(double BHsp, double x_init[4], double x_final[4]) //*************************************************** { printf("BHsp %f\n", BHsp); double r,m,t,phi; t = x_init[0]; r = x_init[1]; m = x_init[2]; phi = x_init[3]; printf("t0 %f\n", t); printf("r0 %f\n", r); printf("m0 %f\n", t); printf("phi0 %f\n", r); t=t+1.0; r=r+1.0; m=m+1.0; phi=phi+1.0; printf("t1 %f\n", t); printf("r1 %f\n", r); printf("m1 %f\n", t); printf("phi1 %f\n", r); x_final[0] = t; x_final[1] = r; x_final[2] = m; x_final[3] = phi; return 0; } 

If I compile and run the program, this is what I get:

x_in, x_fin before = 1.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000000000000000000000000000000000000000 0.0000000000000000 0.0000000000000000

BHsp 0.000000

t0 0.700000

r0 0.000000

m0 0.700000

phi0 0.000000

t1 1.700000

r1 1.000000

m1 1.700000

phi1 1.000000

return rt = 0

x_in, x_fin after = 1.6999999880790710 1.0000000000000000 1.0000000000000000 1.0000000000000000000000000000000000000000000000000000 0.0000000000000000 0.0000000000000000

Please note that before setting the variable "spin", everything works. He could read the input array, make a print, and give the correct conclusion.

Now that I have added the ths variable, there are some problems for the C procedure in reading what I pass, and I cannot understand what happened. Any suggestion?

(Consider that in the real case I'm going to pass in several variables, as well as 2 input and 2 output arrays with size 4).

Thank you very much in advance!

+1
source share
1 answer

Change your interface to:

 module raytracing Interface integer (C_INT) function photon_trace(BHsp, x_init, x_final) & bind(C, name='photon_trace') use , intrinsic :: ISO_C_BINDING implicit none real(C_DOUBLE) :: x_init(4), x_final(4) real(c_double), value :: BHsp end function photon_trace end interface end module raytracing 

Your C function accepts double , not double* , so you need to pass a scalar with the value attribute so that Fortran knows that it is passed by value and not by default by reference.

With this small change (and some minor changes in C to actually print the m and phi values) this is the output of your sample code:

 % ./main x_in, x_fin before = 1.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 BHsp 0.700000 t0 1.000000 r0 2.000000 m0 3.000000 phi0 4.000000 t1 2.000000 r1 3.000000 m1 4.000000 phi1 5.000000 return rt = 0 x_in, x_fin after = 1.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000 5.0000000000000000 
+5
source

Source: https://habr.com/ru/post/1239651/


All Articles