ISO_C_BINDING使用指针调用C例程的Fortran从使用数组 [英] iso_c_binding calling C routine with pointers from Fortran with arrays

查看:240
本文介绍了ISO_C_BINDING使用指针调用C例程的Fortran从使用数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我挖在论坛上寻找一个解决方案,但我失败了。我的主要问题是我太用C语言和Fortran-C的互操作性小白才能明白我做错了什么究竟。

I digged on the forum looking for a solution but I failed. My main problem is I am too noob with C language and Fortran-C interoperability in order to understand what I am doing wrong exactly.

我要调用的Fortran从一个C程序,但我有与变量的声明问题。我做了一个例子。

I want to call a C routine from Fortran but I'm having problem with the declaration of the variables. I made an example.

这是C例程:

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

}

这是用Fortran主程序:

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 the module with the 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  

根据谁给我的例程C, x_init x_final 应该是三分球的家伙(右? )。

According to the guy who gave me the routine in C, x_init and x_final should be pointers (right?).

当我尝试编译它给了我在 photon_trace 在主程序参数列表当我打电话了错误。

When I try to compile it gives me an error in argument list when I call photon_trace in the main program.

有什么建议?我用gcc 4.8

Any suggestions? I'm using gcc 4.8

P.S。请问GCC 4.4具有对于相同的能力,以 ISO_C_BINDING 或我需要做一些不同的使用它?

P.S. Does gcc 4.4 have the same capabilities with respect to iso_c_binding or will I need to do something different for using it?

修改后VLADIMIR注释:

感谢弗拉基米尔!我打电话的功能,因为我见过这样的例子<一个href=\"http://stackoverflow.com/tags/fortran-iso-c-binding/info\">http://stackoverflow.com/tags/fortran-iso-c-binding/info

Thanks Vladimir! I was calling the function because I saw it on this example http://stackoverflow.com/tags/fortran-iso-c-binding/info

我给你建议的修改,它现在编译!
问题是C例程似乎与变量的地址,而不是变量本身工作。

I made the modification you suggested and it compiles now! Problem is that the C routine seems to work with the address of the variables and not the variables itself.

我把一些印在C程序:

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;

}

和在主体

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 that's what is 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 happening here?

在提前为precious帮助非常感谢!

Many thanks in advance for the precious help!!

推荐答案

不要过度复杂化了。不及格的指针,而是通过引用传递数组

Do not over-complicate it. Don't pass the pointers, but pass the arrays by reference

此外,函数必须在离pression使用,而不是在调用语句。

Also, a function must be used in an expression, not in a call statement.

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
      real(c_double) :: x_init(4), x_final(4)
    end function photon_trace
  end interface
end module raytracing  

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_double), dimension(0:3) :: x_in, x_fin
integer ie

x_in = (/1,2,3,4/)
x_fin = (/0,0,0,0/)


write(*,*)'x_in, x_fin before = ', x_in, x_fin
ie = photon_trace(x_in,x_fin)
write(*,*)'x_in, x_fin after = ', x_in, x_fin


end program main_dummy

在C可互操作的Fortran程序通过指针变量,除非你使用。这就是所谓的按引用传递

In C interoperable procedures Fortran passes pointers to the variables, unless you use value. This is called pass by reference.

> gfortran ray.c ray.f90
> ./a.out 
 x_in, x_fin before =    1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000        0.0000000000000000     
 x_in, x_fin after =    1.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        2.0000000000000000        3.0000000000000000        4.0000000000000000        5.0000000000000000

P.S。 GCC 4.4很老,但它在理论上它知道的C互操作的东西。试试吧,你会看到的。

P.S. gcc 4.4 very old, but it theoretically it knows the C interop stuff. Try it and you will see.

这篇关于ISO_C_BINDING使用指针调用C例程的Fortran从使用数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆