通过调用Fortran中的C ++函数将Fortran int数组传递给C ++

时间:2010-05-13 09:58:44

标签: c++ fortran

我试图在Fortran子程序中调用C ++函数。该C ++函数应该更新整数数组。这是我写的一个非工作代码。有什么问题?

! Fortran function that calls a C++ function.

subroutine my_function()

      integer(4) ar(*)

      integer(4) get_filled_ar

      ! Need correct syntax here.
      ar = get_filled_ar()
end


// C++ function:

    extern "C" {
        void get_filled_ar(int *ar){
            ar[0] = 1;
            ar[1] = 10;
            ar[3] = 100;
        }
    }

2 个答案:

答案 0 :(得分:7)

使用Fortran 2003,有一种标准的,因此平台和编译器独立的方式来从Fortran调用C,以及任何使用C调用接口的语言。也是从C调用Fortran。虽然各种编译器编写者正在逐步添加Fortran 2003功能,并且几乎没有完整的2003编译器,但ISO C Binding在许多编译器中已经有一段时间了。 ISO C Binding比以前的ad hoc技术工作得更好,这些技术有时记录很少,并且在编译器和平台之间有所不同。要从Fortran调用C,您编写一个“接口”,告诉Fortran编译器它应该使用C调用约定和C类型。

这是一个例子。正如Mike写的那样,由于C ++函数返回void,因此将它作为子例程在Fortran中处理并调用它。因此,不需要给出类型。此外,在Fortran中的某个位置,您必须为数组保留存储空间 - 最简单的方法是使用维度的数值进行声明。而且你需要某种语言的主程序。

program test_call_C

use iso_c_binding

implicit none

interface c_interface

   subroutine get_filled_ar (ar) bind (C, name = "get_filled_ar")

   use iso_c_binding

   implicit none

   integer (c_int), intent (out), dimension (*) :: ar

   end subroutine get_filled_ar

end interface c_interface


integer (c_int), dimension (0:3) :: ar

call get_filled_ar (ar)

write (*, *) "Fortran: ar:", ar

stop

end program test_call_C

并在C:

void get_filled_ar (
   int ar []
) {

   ar [0] = 1;
   ar [1] = 10;
   ar [2] = 100;

   return;

}

示例命令:

gcc -c get_filled_ar.c
gfortran get_filled_ar.o test_call_C.f90  -o test_call_C.exe
./test_call_C.exe

要调用C ++代码,请使用以下命令。 “绑定”中指定的名称不需要使用尾随下划线,因此您的C ++代码可以直接使用。

g++ -c cplusplus.cc
gfortran cplusplus.o test_call_C.f90  -o test_call_Cplusplus.exe
./test_call_Cplusplus.exe

答案 1 :(得分:2)

这是一个完整的程序,其中包含您的代码(至少在Linux上使用gcc / gfortran)。

在fortran文件fortran.f中,输入:

     IMPLICIT NONE      
     CALL my_function()
     END

! FORTRAN function that calls a C++ function

     subroutine my_function()
! Tell fortran about the C++ function:
       external get_filled_ar

       integer ar(4)

! As the C++ function returns void, call it as a subroutine in
! fortran:
       call get_filled_ar(ar)
! To check it worked, print out the numbers:
       do i = 1,4
          write(*,*) i,"->",ar(i)
       enddo
     end

cplusplus.cc put:

extern "C"
{
  void get_filled_ar_(int* ar) // note extra underscore to keep linker happy
  {
    ar[0] = 1;   
    ar[1] = 10;
    ar[3] = 100;
  }    
}

然后在(使用gcc / gfortran的linux上构建,在其他系统上可能会有所不同):

gfortran -c fortran.f
gcc -c cplusplus.cc
gfortran -o program-name fortran.o cplusplus.o