从 C 调用 FORTRAN 子例程

2023-11-24

我正在尝试从 C 调用 FORTRAN 函数

我的问题是:

  1. If fortRoutine是我的 Fortran 子例程的名称,那么我从 C 调用它 作为fortRoutine_. If fortRoutine仅包含一个字符数组参数,那么我可以这样传递:

    fortRoutine_("I am in fortran");
    
  2. 调用 FORTRAN 子例程时,什么时候应该使用按值传递,什么时候应该使用按引用传递?

由于我是C语言新手,所以我对此一无所知。如果可能的话,请推荐一些好的教程链接。


现在执行此操作的方法是在 Fortran 端使用 Fortran ISO C 绑定。这是 Fortran 2003 语言标准的一部分,可在许多编译器中使用;它不是特定于 gcc 的。本网站的许多答案中都对此进行了描述。作为语言标准的一部分,它独立于编译器和平台。并且您不需要了解编译器的内部传递约定。 ISO C 绑定在 Fortran 子例程或函数的声明中使用时,会导致 Fortran 编译器使用 C 调用约定,以便可以直接从 C 调用该过程。您不需要添加隐藏参数或名称修改Fortran 子例程名称,即没有下划线。链接器使用的名称来自“bind”选项。

字符串是一个困难的情况,因为从技术上讲,在 C 中它们是字符数组,并且您必须在 Fortran 中匹配它。您还必须处理字符串的不同定义:C 以 null 结尾,Fortran 固定长度并用空格填充。该示例展示了这是如何工作的。数字更容易。数组的唯一问题是 C 是行优先而 Fortran 是列优先,因此多维数组会被转置。

int main ( void ) {

   char test [10] = "abcd";

   myfortsub (test);

   return 0;

}

and

subroutine myfortsub ( input_string ) bind ( C, name="myfortsub" )

   use iso_c_binding, only: C_CHAR, c_null_char
   implicit none

   character (kind=c_char, len=1), dimension (10), intent (in) :: input_string
   character (len=10) :: regular_string
   integer :: i

   regular_string = " "
   loop_string: do i=1, 10
      if ( input_string (i) == c_null_char ) then
         exit loop_string
      else
         regular_string (i:i) = input_string (i)
      end if
   end do loop_string

   write (*, *) ">", trim (regular_string), "<", len_trim (regular_string)

   return

end subroutine myfortsub

您将 C 编译为目标文件,然后使用 gfortran 编译 fortran 并链接两者:

gcc-mp-4.6   \
         -c  \
         test_fortsub.c

gfortran-mp-4.6   \
     test_fortsub.o  \
     myfortsub.f90  \
     -o test_fortsub.exe

输出是:

 >abcd<           4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C 调用 FORTRAN 子例程 的相关文章

随机推荐