salto resueltos programas programaciĆ³n problemas linea intrinsecas funciones ejemplos fortran fortran-iso-c-binding

resueltos - ISO_C_BINDING Llamando a la rutina C desde Fortran(con dobles y matrices)



programas en fortran ejemplos (1)

Publiqué una pregunta similar hace unas semanas ( iso_c_binding llamando a la rutina C con punteros de Fortran con matrices ) y encontré una solución a mi problema. Ahora modifiqué algunas cosas y estoy teniendo algunos problemas otra vez. A continuación, una versión simplificada de mi problema.

Tengo un programa principal en 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

Que usan una subrutina que contiene la interfaz para la rutina 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

y esta es la rutina C:

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

Si compilo y ejecuto el programa, esto es lo que obtengo:

x_in, x_fin before = 1.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000 0.0000000000000000 0.0000000000000000 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 después = 1.6999999880790710 1.0000000000000000 1.0000000000000000 1.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000

Tenga en cuenta que antes de poner la variable "spin" todo estaba funcionando. Podría leer la matriz de entrada, hacer la opración y dar la salida correcta.

Ahora que agregué esta variable, hay algunos problemas para la rutina C al leer lo que estoy pasando y no puedo entender qué sucede. Cualquier sugerencia ?

(Tenga en cuenta que en el caso real voy a pasar varias variables, así como 2 matrices de entrada y 2 de salida con dimensión 4).

¡¡Muchas gracias de antemano!!


Cambie su interfaz a:

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

Su función C toma un double lugar de un double* por lo que debe pasar el escalar con el atributo de value para que el Fortran sepa pasar el valor en lugar de su pase predeterminado por referencia.

Con este pequeño cambio (y algunos cambios menores en su C para imprimir realmente los valores de m y phi ) este es el resultado de su código de ejemplo:

% ./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