I dug up on the forum looking for a solution, but I failed. My main problem is that I'm too noob with C language and Fortran-C compatibility to understand what I'm doing wrong.
I want to call the C routine from Fortran, but I have a problem with declaring variables. I made an example.
This is the C routine:
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> #undef I int photon_trace(double x_init[4], double x_final[4]) //*************************************************** { double r,m,t,phi; t = x_init[0]; r = x_init[1]; m = x_init[2]; phi = x_init[3]; t=t+1.0; r=r+1.0; m=m+1.0; phi=phi+1.0; x_final[0] = t; x_final[1] = r; x_final[2] = m; x_final[3] = phi; return 0; }
This is the main program in Fortran:
program main_dummy ! compile: f95 raytracing.f90 main_dummy.f90 dummy_trace.o -o main use, intrinsic :: ISO_C_BINDING use raytracing implicit none real(C_FLOAT), dimension(0:3) :: x_in, x_fin x_in = (/1,2,3,4/) x_fin = (/0,0,0,0/) write(*,*)'x_in, x_fin before = ', x_in, x_fin call photon_trace(C_FLOAT(x_in),C_FLOAT(x_fin)) write(*,*)'x_in, x_fin after = ', x_in, x_fin end program main_dummy
And this is a module with an interface:
module raytracing Interface integer (C_INT) function photon_trace(x_init, x_final) & bind(C, name='photon_trace') use , intrinsic :: ISO_C_BINDING implicit none type (c_ptr), value :: x_init, x_final end function photon_trace end interface end module raytracing
According to the guy who gave me the routine in C, x_init and x_final should be pointers (right?).
When I try to compile, it gives me an error in the argument list when I call photon_trace in the main program.
Any suggestions? I am using gcc 4.8
PS Does gcc 4.4 have the same features regarding iso_c_binding , or do I need to do something else to use it?
CHANGE AFTER VLADIMIR:
Thanks to Vladimir! I was calling a function because I saw it in this example https://stackoverflow.com/a/4646262
I made the modification you proposed, and now it compiles! The problem is that the C routine works with the address of the variables, not the variables themselves.
I put some print in the C routine:
int photon_trace(double x_init[4], double x_final[4]) //*************************************************** { 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; }
as well as mainly:
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_FLOAT), dimension(0:3) :: x_in, x_fin integer :: rt_ok x_in = (/1,2,3,4/) x_fin = (/0,0,0,0/) write(*,*)'x_in, x_fin before = ', x_in, x_fin rt_ok = photon_trace(x_in,x_fin) write(*,*)'return rt = ', rt_ok write(*,*)'x_in, x_fin after = ', x_in, x_fin end program main_dummy
and what's on the screen:
x_in, x_fin before = 1.00000000 2.00000000 3.00000000 4.00000000 0.00000000 0.00000000 0.00000000 0.00000000 t0 2.000000 r0 512.000123 m0 2.000000 phi0 512.000123 t1 3.000000 r1 513.000123 m1 3.000000 phi1 513.000123 return rt = 0 x_in, x_fin after = 1.00000000 2.00000000 3.00000000 4.00000000 1.00000000 2.12500000 3.00000000 4.00097656
What's going on here?
Thank you very much for your precious help!