当函数放入使用“ar rcs”创建的库中时,遇到从C++调用FORTRAN子例程的问题。从C++调用FORTRAN库的问题
Fortran例程(tt.f90)为:
Module A
contains
Subroutine SubIF2(ii)
Integer*8, Intent(In) :: ii
write(*,*) "hello", ii
End Subroutine SubIF2
End Module A
一个C++调用者(testcpp.cpp)码是
#include <iostream>
using namespace std;
extern"C" {
void __a_MOD_subif2(long long int *ii);
}
main(){
long long int ii=5;
__a_MOD_subif2(&ii);
return 0;
}
一个FORTRAN呼叫者(testf.f90)码是
Program test
use A
integer*8 :: i=1
call SubIF2(i)
End Program test
makefile是
p=/PathToMyWorkDirectory
all:
gfortran -c tt.f90
ar rcs libtt.a tt.o
g++ -c testcpp.cpp
gfortran -c testf.f90
-gfortran -o testf90 testf.o tt.a
-g++ tt.o testcpp.o -o testcpp -lgfortran
-g++ -L$(p) -ltt testcpp.o -o testcpp -lgfortran
clean:
-rm *.o *.mod
-rm testf90
-rm testcpp
尽管“gfortran -o testf90 testf.o tt.a”和“g ++ tt.o testcpp.o -o testcpp -lgfortran”产生了可用的可执行文件,“g ++ -L $(p)-ltt testcpp。 Ø-o testcpp -lgfortran”崩溃
testcpp.o: In function `main':
testcpp.cpp:(.text+0x18): undefined reference to `__a_MOD_subif2'
collect2: error: ld returned 1 exit status
因为用于FORTRAN的可执行链接的作品,我看不出什么错在库的创建。
任何想法,我在这里失踪?
非常感谢。
注意:最终的fortran函数都是二进制的,所以调整fortran代码(例如iso_c_binding)不是一个选项。
注意:如果你把子程序超出了Fortran模块的你将不再需要特定的编译器'.mod'文件,你将能够直接调用子程序,而不需要'__a_MOD_'前缀,这是不可移植的。在我看来,Fortran库应该展示一个无模块的界面,使用户更容易。 –
有一些没有尾随的下划线开关可能有用。或者你可以在c中添加尾部下划线。另外,如果f90例程是公共的或使用!DEC $ ATTRIBUTES ALIAS:subif2 :: subif2,那么可以提供帮助。 – Holmz
@Holmz'bind(C,name =“”)'比旧的DEC ALIAS好得多。更重要的是,这个问题是关于gfortran和gfortran完全不关心'DEC ATRTRIBUTES'。难怪,它不是DEC而是GNU。 –