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

2022-09-20  本文已影响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

可以发现几个问题:

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

Oracle Chapter 11 C-FortranInterface

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

上一篇 下一篇

猜你喜欢

热点阅读