从Fortran调用C例程的ISO_C_绑定(带双精度和数组)

从Fortran调用C例程的ISO_C_绑定(带双精度和数组),fortran,fortran-iso-c-binding,Fortran,Fortran Iso C Binding,几周前我发布了一个类似的问题(),我找到了解决问题的方法。 现在我修改了一些东西,我又遇到了一些问题。 下面是我问题的简化版本 我有一个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 non

几周前我发布了一个类似的问题(),我找到了解决问题的方法。 现在我修改了一些东西,我又遇到了一些问题。 下面是我问题的简化版本

我有一个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
使用包含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 
#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;

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

}
#包括
#包括
#包括
#包括
#未定义I
整数光子跟踪(双BHsp,双x初始[4],双x最终[4])
//***************************************************
{
printf(“BHsp%f\n”,BHsp);
双r,m,t,φ;
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;
φ=φ+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]=φ;
返回0;
}
如果我编译并运行程序,我得到的是:

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

0.000000南非兰特

m0.700000

phi0.000000

t1 1.700000

1100万南非兰特

m1 1.700000

PHI11.000000

返回rt=0

x_in,x_fin after=1.699999880790710 1.0000000000000000000000 1.0000000000000000000000 0.0000000000000000000000 0.0000000000000000000000 0.0000000000000000000000 0.0000000000000000000000

请注意,在放入变量“spin”之前,一切都正常。它可以读取输入数组,进行运算,并给出正确的输出

现在我添加了这个变量,C例程在读取我传递的内容时遇到了一些问题,我无法理解哪里出了问题。 有什么建议吗

(考虑一下,在实际情况中,我将传递几个变量以及维度为4的2个输入和2个输出数组)


非常感谢

将您的界面更改为:

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 
C函数采用的是
double
而不是
double*
,因此需要使用
value
属性传递标量,以便Fortran知道按值传递,而不是默认的按引用传递

通过这个小改动(以及对C的一些小改动,以实际打印
m
phi
的值),这就是示例代码的输出:

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

将界面更改为:

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 
C函数采用的是
double
而不是
double*
,因此需要使用
value
属性传递标量,以便Fortran知道按值传递,而不是默认的按引用传递

通过这个小改动(以及对C的一些小改动,以实际打印
m
phi
的值),这就是示例代码的输出:

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

凯西,你能看看这个问题吗?我想对你来说,这件事和这件一样微不足道!谢谢凯西,你能看看这个问题吗?我想对你来说,这件事和这件一样微不足道!非常感谢。