2016-08-17 72 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