从 C 调用 FORTRAN 子例程 [英] Calling a FORTRAN subroutine from C

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

问题描述

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

I am trying to call a FORTRAN function from C

我的问题是:

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

  1. If fortRoutine is the name of my fortran subroutine, then I am calling this from C as fortRoutine_. If fortRoutine contains only one character array argument, then can I pass like this:

fortRoutine_("I am in fortran");

  • 在调用 FORTRAN 子程序时,什么时候应该使用传值和传引用?

  • While calling FORTRAN subroutines, when should I use pass by value and when pass by reference?

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

    As I am new to C, I do not have a clue about this. If possible, please suggest some good tutorial links as well.

    推荐答案

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

    The way to do this now is to use the Fortran ISO C Binding on the Fortran side. This is part of the Fortran 2003 language standard and is available in many compilers; it is not specific to gcc. It has been described in many answers on this site. As part of the language standard, it is compiler and platform independent. And you do not need to know about the internal passing conventions of the compiler. The ISO C Binding, when used in the declaration of a Fortran subroutine or function, causes the Fortran compiler to use the C calling conventions so that that procedure can be directly called from C. You do not need to add hidden arguments or name mangle the Fortran subroutine name, i.e., no underscores. The name used by the linker comes from the "bind" option.

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

    Strings are a difficult case because technically in C they are arrays of characters and you have to match this in the Fortran. You also have to deal with the different definitions of strings: C is null terminated, Fortran fixed length and padded with blanks. The example shows how this works. Numbers are easier. The only issue with arrays is that C is row-major and Fortran column-major so that multi-dimensional arrays are transposed.

    int main ( void ) {
    
       char test [10] = "abcd";
    
       myfortsub (test);
    
       return 0;
    
    }
    

    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 并链接两者:

    You compile the C to an object file and use gfortran to compile the fortran and link both:

    gcc-mp-4.6   
             -c  
             test_fortsub.c
    
    gfortran-mp-4.6   
         test_fortsub.o  
         myfortsub.f90  
         -o test_fortsub.exe
    

    输出是:

     >abcd<           4
    

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

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