2016-08-17 44 views
1

当函数放入使用“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)不是一个选项。

+1

注意:如果你把子程序超出了Fortran模块的你将不再需要特定的编译器'.mod'文件,你将能够直接调用子程序,而不需要'__a_MOD_'前缀,这是不可移植的。在我看来,Fortran库应该展示一个无模块的界面,使用户更容易。 –

+0

有一些没有尾随的下划线开关可能有用。或者你可以在c中添加尾部下划线。另外,如果f90例程是公共的或使用!DEC $ ATTRIBUTES ALIAS:subif2 :: subif2,那么可以提供帮助。 – Holmz

+1

@Holmz'bind(C,name =“”)'比旧的DEC ALIAS好得多。更重要的是,这个问题是关于gfortran和gfortran完全不关心'DEC ATRTRIBUTES'。难怪,它不是DEC而是GNU。 –

回答

2

,你必须指定使用在其定义的符号的目标文件,即在图书馆,

g++ -o testcpp testcpp.o -L. -ltt -lgfortran 
+0

这很快。非常感谢 – user1407220