Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran模块与在C中访问的过程相结合,反之亦然_C_Module_Compilation_Fortran_Mixed Code - Fatal编程技术网

Fortran模块与在C中访问的过程相结合,反之亦然

Fortran模块与在C中访问的过程相结合,反之亦然,c,module,compilation,fortran,mixed-code,C,Module,Compilation,Fortran,Mixed Code,我正在尝试使用模块和过程测试Fortran/C混合语言。我使用了此链接中的基本示例案例: 但是当我试图修改代码时,我开始出现如下错误 "_initfo_", reference from: _MAIN__ in main.o ld: symbol(s) not found for architecture x86_64. 这是我的密码: new.F >> MODULE EXAMP use iso_c_binding REAL, bind(

我正在尝试使用模块和过程测试Fortran/C混合语言。我使用了此链接中的基本示例案例: 但是当我试图修改代码时,我开始出现如下错误

"_initfo_", reference from: _MAIN__ in main.o
ld: symbol(s) not found for architecture x86_64. 
这是我的密码:

new.F >>
      MODULE EXAMP
      use iso_c_binding
         REAL, bind(C) :: A(3)
         INTEGER I1, I2
         CHARACTER(80) LINE
         TYPE MYDATA
             SEQUENCE
             INTEGER N
             CHARACTER(30) INFO
          END TYPE MYDATA
      END MODULE EXAMP
cnew.c >>
/* C  code accessing module data */
extern float a[3];
extern int examp_mp_i1, examp_mp_i2;
extern char examp_mp_line[80];
//extern void usemodule();
extern struct {
    int n;
    char info[30];
} examp_mp_mydata;

void pythagoras (float *c){
    *c = (float) sqrt(a[0]*a[0] + a[1]*a[1]);
}

void initfo(float *aa){
     *aa = a[0]+a[1]+a[2];
}
main.F >>
! Fortran 95/90 Module including procedure
      MODULE CPROC
        INTERFACE
            SUBROUTINE PYTHAGORAS ( res)
            !DEC$ ATTRIBUTES C :: PYTHAGORAS
            !DEC$ ATTRIBUTES REFERENCE :: res
! res is passed by REFERENCE because its individual attribute
!: overrides the subroutine's C attribute
            REAL res
! a and b have the VALUE attribute by default because
! the subroutine has the C attribute
            END SUBROUTINE
        END INTERFACE
        END MODULE

! Fortran 95/90 Module including procedure
      MODULE CCPROC
        INTERFACE
            SUBROUTINE INITFO (aa)
            REAL aa
            END SUBROUTINE
        END INTERFACE
        END MODULE

        PROGRAM MAIN
        USE EXAMP
! Fortran 95/90 Module including procedure
        USE CPROC
        USE CCPROC
        A(1)=1.0
        A(2)=2.0
        A(3)=3.0
        WRITE(*,*) A(1)
        CALL PYTHAGORAS ( X)
        WRITE(*,*) X

        CALL INITFO(Y)
        WRITE(*,*) Y
        END PROGRAM MAIN
我正在使用英特尔编译器。 这是我编译时所做的:

icc -c cnew.c
ifort -c new.f
ifort -o test main.f new.o cnew.o
我对fortran真的很陌生。我真的希望有人能给我指出一个正确的方向

谢谢


Jing

使用Fortran 2003,您可以这样声明接口:

  INTERFACE
      SUBROUTINE PYTHAGORAS (res) bind(c, name='pythagoras')
        use iso_c_binding
        real(kind=c_float) :: res
      END SUBROUTINE

      SUBROUTINE initfo (aa) bind(c, name='initfo')
        use iso_c_binding
        real(kind=c_float) :: aa
      END SUBROUTINE
  END INTERFACE
这里的要点是添加到子程序声明中的name属性,它告诉编译器实际使用哪个符号。否则,名称mangling将为您提供找不到的实体

总共给出:new.f90

main.f90:


c代码保持不变。我强烈建议您不要使用像
a

这样的全局变量,谢谢您对我的代码进行了宝贵的修改。它运行得很好。我能知道为什么使用have“a”作为全局变量是个坏主意吗?此外,fortran中的公共块也是某种全局变量吗?代码中有很多公共块是好还是坏?如果不好,你有什么建议使代码更好更安全?@JingYang Common Block已经过时,不应该在新代码中使用。它们很容易引起混淆。在某些地方可以用来取代它的现代结构是模块变量。全局变量是不好的,因为它们使读者感到困惑,并且很难跟踪。此外,它们可能会禁止编译器执行优化。如果您传递所需的变量,数据流将变得更加可见。例程的有限范围对读者和编译器都有帮助。感谢您的及时回复。您能更具体地说明如何修改我的全局变量吗?你的意思是将“a”传递到每个可以访问“a”的子例程中,还是在模块部分,我应该将变量放在类似“real,public::a(3)”的地方?是的,传递的意思是将它定义为一个参数,就像毕达哥拉斯例程中的
res
。谢谢你的回答。我从你身上学到了很多。你能再回答我一个问题吗?现在,我正在尝试修改C和fortran之间的派生类型。我仍然得到未找到的符号错误。我已经将bind(c)作为类型,bind(c)::MYDATA并删除了序列标记。C代码仍然无法识别mydata…对此有什么想法吗?
MODULE EXAMP
  use iso_c_binding

  REAL(kind=c_float), bind(c) :: A(3)
  INTEGER :: I1, I2
  CHARACTER(80) :: LINE

  TYPE MYDATA
     SEQUENCE
     INTEGER :: N
     CHARACTER(len=30) :: INFO
  END TYPE MYDATA

END MODULE EXAMP
MODULE CPROC
  use iso_c_binding
  INTERFACE
      SUBROUTINE PYTHAGORAS (res) bind(c, name='pythagoras')
        use iso_c_binding
        real(kind=c_float) :: res
      END SUBROUTINE

      SUBROUTINE initfo (aa) bind(c, name='initfo')
        use iso_c_binding
        real(kind=c_float) :: aa
      END SUBROUTINE
  END INTERFACE
END MODULE

PROGRAM MAIN
   USE EXAMP
! Fortran 95/90 Module including procedure
   USE CPROC

   A(1)=1.0
   A(2)=2.0
   A(3)=3.0
   WRITE(*,*) A(1)
   CALL PYTHAGORAS(X)
   WRITE(*,*) X

   CALL INITFO(Y)
   WRITE(*,*) Y
END PROGRAM MAIN