gpt4 book ai didi

fortran - ISO_C_BINDING 从 Fortran 调用 C 例程(使用 double 和数组)

转载 作者:太空宇宙 更新时间:2023-11-04 04:12:26 28 4
gpt4 key购买 nike

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

我有一个用 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 例程接口(interface)的子例程:

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

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

}

如果我编译并运行程序,这就是我得到的:

x_in,x_fin之前= 1.00000000000000002.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000来不起0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

>

BHsp 0.000000

t0 0.700000

r0 0.000000

m0 0.700000

φ0 0.000000

t1 1.700000

r1 1.000000

立方米 1.700000

phi1 1.000000

返回 rt = 0

x_in, x_fin after = 1.6999999880790710 1.0000000000000000 1.0000000000000000 1.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000

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

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

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

提前致谢!

最佳答案

将您的界面更改为:

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 进行一些小改动以实际打印 mphi 的值),这就是示例代码的输出:

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

关于fortran - ISO_C_BINDING 从 Fortran 调用 C 例程(使用 double 和数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55702938/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com