Fortran模块与在C中访问的过程相结合,反之亦然
我正在尝试使用模块和过程测试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(
"_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