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

发布于 2024-09-01 17:57:15 字数 460 浏览 5 评论 0原文

我正在尝试在 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;
        }
    }

I am trying to call a C++ function in a Fortran subroutine. This C++ function is supposed to update an integer array. Here is a non-working code I wrote. What is the issue?

! 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;
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

删除会话 2024-09-08 17:57:15

Fortran 2003 提供了一种标准的、独立于平台和编译器的方法来从 Fortran 调用 C,以及使用 C 调用接口的任何语言。还要从 C 调用 Fortran。虽然各个编译器编写者正在逐渐添加 Fortran 2003 功能,并且几乎没有完整的 2003 编译器,但 ISO C 绑定在许多编译器中已经可用了一段时间。 ISO C 绑定比以前的临时技术工作得更好,这些技术有时记录很少,并且在编译器和平台之间存在差异。要从 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++ 代码,请使用以下命令。 “bind”中指定的名称不需要尾随下划线,因此您的 C++ 代码可以直接运行。

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

With Fortran 2003 there is a standard and thus platform and compiler independent way to call C from Fortran, and also any language that uses the C calling interface. Also to call Fortran from C. While the various compiler writers are gradually adding Fortran 2003 features and there are few complete 2003 compilers, the ISO C Binding has been available for some time in many compilers. The ISO C Binding works better than the previous ad hoc techniques, which were sometimes poorly documented, and varied between compilers and platforms. To call C from Fortran, you write an "interface" that tells the Fortran compiler that it should use the C calling conventions, and C types.

Here is an example. As Mike wrote, since the C++ function returns void, treat it in the Fortran as a subroutine and call it. Thus it doesn't need to be given a type. Also, somewhere in the Fortran you have to reserve storage for the array -- the easiest way is with a declaration with numeric value for the dimension. And you need a main program in some language.

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

and in C:

void get_filled_ar (
   int ar []
) {

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

   return;

}

Example commands:

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

To call your C++ code, use the following commands. The name specified in the "bind" obviates the need for a trailing underscore so your C++ code works directly.

g++ -c cplusplus.cc
gfortran cplusplus.o test_call_C.f90  -o test_call_Cplusplus.exe
./test_call_Cplusplus.exe
吻安 2024-09-08 17:57:15

这是一个完整的程序,其中包含您的代码,应该可以工作(至少在使用 gcc/gfortran 的 linux 上)。

在 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 中输入:

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

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

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

Here's a full program with your code in it that should work (at least on linux with gcc/gfortran).

In the fortran file fortran.f, put:

     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

In 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;
  }    
}

Then build (on linux with gcc/gfortran, might be different on other systems) with:

gfortran -c fortran.f
gcc -c cplusplus.cc
gfortran -o program-name fortran.o cplusplus.o
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文