美文网首页
FORTRAN调用C函数的参数不一致问题-自动额外传参特性

FORTRAN调用C函数的参数不一致问题-自动额外传参特性

作者: 别有路 | 来源:发表于2022-09-20 10:14 被阅读0次

    最近在debug的时候看到CMAQ ioapi的code, envgets.c中和ENVSTR函数和m3utilio.F中的接口参数不一致, 但是可以正常跑, 之前没注意过, 我大为震惊, code如下:

    // ioapi/envgets.c
    void ENVSTR( const char * lname, 
                 const char * description, 
                 const char * defaultval, 
                 char       * eqname, 
                 FINT       * status,
                 FSTR_L       namlen, 
                 FSTR_L       deslen, 
                 FSTR_L       deflen, 
                 FSTR_L       eqlen )
    {
        ... ...
    }
    
    ! ioapi/m3utilio.F
    INTERFACE
        SUBROUTINE ENVSTR( LNAME, DESC, DEFAULT, EQNAME, STAT )
        CHARACTER*(*), INTENT(IN   ) :: LNAME
        CHARACTER*(*), INTENT(IN   ) :: DESC
        CHARACTER*(*), INTENT(IN   ) :: DEFAULT
        CHARACTER*(*), INTENT(  OUT) :: EQNAME
        INTEGER      , INTENT(  OUT) :: STAT
        END SUBROUTINE ENVSTR
    END INTERFACE
    

    然后自己做了个简单的测试

    // echo.c
    #include<stdio.h>
    
    void echo_(const char *s1, const char *s2)
    {
      printf("%s\n", s1);
      printf("%s\n", s2);
    }
    
    void echo2_(char *s1, char *s2, int l1, int l2)
    {
      printf("%s\n", s1);
      printf("%s\n", s2);
        printf("%d\n", l1);
        printf("%d\n", l2);
    }
    
    ! main.f90
    PROGRAM main
    implicit none
    INTEGER :: a, b, c, e
    CHARACTER(14) :: s1, s2
    INTERFACE
      SUBROUTINE ECHO(s1, s2)
        CHARACTER(*) :: s1, s2
      END SUBROUTINE
      SUBROUTINE ECHO2(s1, s2)
        CHARACTER(*) :: s1, s2
      END SUBROUTINE
    END INTERFACE
    
    s1 = "1234567890123" ! // achar(0)
    s2 = "world"
    
    call ECHO(s1, s2)
    call ECHO2(s1, s2)
    
    
    END PROGRAM main
    
    # makefile
    test :
            icc -c -o echo.o echo.c
            ifort -c -o main.o main.f90
            ifort main.o echo.o -o main.exe
    

    执行得:

    1234567890123 world
    world
    14
    14
    

    可以发现几个问题:

    • FORTRAN和C的参数个数确实不需要匹配也ok
    • 字符串在从FORTRAN到C的时候是会出问题的(第一行直接打印s1有明显错误)
    • 会在FORTRAN的参数后面加上字符串的长度(我推测这个机制和上一点是有关系的)

    然后经过查证, 在官方的doc里确实也提到了这个feature, 之前没注意到这么细

    Oracle Chapter 11 C-FortranInterface

    另外这个只是针对字符串的, 试了下对数组是不会带长度的, 但是参数不需要匹配就能跑是都行的, 只是其他情况大概会报错

    相关文章

      网友评论

          本文标题:FORTRAN调用C函数的参数不一致问题-自动额外传参特性

          本文链接:https://www.haomeiwen.com/subject/apubortx.html