从Fortran调用C例程的ISO_C_绑定(带双精度和数组)
几周前我发布了一个类似的问题(),我找到了解决问题的方法。 现在我修改了一些东西,我又遇到了一些问题。 下面是我问题的简化版本 我有一个fortran主程序:从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
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
凯西,你能看看这个问题吗?我想对你来说,这件事和这件一样微不足道!谢谢凯西,你能看看这个问题吗?我想对你来说,这件事和这件一样微不足道!非常感谢。