2013-03-21 273 views
2

我包括一個fortran90程序,它不在我的C++項目中。如何在C++代碼中調用包含在模塊中的Fortran90函數?

在第一個步驟中,我嘗試通過name_()調用函數,並通過顯示obj文件的符號(使用nm)得到錯誤「undefined reference to mp_mpi_cartesian_init_」,我發現該函數被調用他們作爲module_function_所以我模塊添加模塊的名字,我也得到了同樣的問題,但FORTRAN OBJ之間,如「Constants.f90 :(文字+ 0x36):未定義的引用__powi4i4」

這裏是C++代碼:

,這是一個模塊的爲例:

MODULE mod_save_wave 

USE mod_constants 
USE mod_MPI_CARTESIAN 

    USE mod_time_mesure, ONLY : tempsEcoule 
    USE mod_input_data, ONLY : Nt_laserPsansLaser 
    USE mod_input_data, ONLY : n_phi, n_rho1_seg, n_rho2_seg 
    USE mod_input_data, ONLY : Nt_periode, save_periodique 


    !//////////////////////////////////////////////////////////////// 
    IMPLICIT NONE       ! 
    REAL(kind=d_t)  :: prog_start_time, time_max_second ! 
    character(len=80) :: IntermedWaveDir 
    !================================================================ 


CONTAINS 

SUBROUTINE begin_count_time() 
    IMPLICIT NONE 

    prog_start_time = tempsEcoule()     ! 

END SUBROUTINE begin_count_time 


SUBROUTINE READ_IT_PSI(it, psi_E1E2) 
    IMPLICIT NONE 
    !//////////////////////////////////////////////////////////////////////////////// 
    INTEGER        :: it  ! 
    COMPLEX(kind=d_t), DIMENSION(n_phi,n_rho1_seg,n_phi,n_rho2_seg) :: psi_E1E2 ! 
    !================================================================================ 

    integer :: c 

    do c = 0, c_max-1 
     if(mod(iproc,c_max)==c) then 

      !//////////////////////////////////////////////////////////////////////////////// 
      OPEN(unit=11,file=concat(trim(IntermedWaveDir),concat(concat('BACK/wave_',str_iproc),'_2p2p2')),& 
          status='old', form='unformatted', MODE='READ'  ) 
       READ(11) it        ! 
       READ(11) psi_E1E2       ! 
      CLOSE(11)         ! 
      print*,'iproc,readed it=',iproc, it 

     endif 

     CALL MPI_BARRIER(MPI_COMM_WORLD,infompi)     ! 
     !================================================================================ 
    enddo 
    !================================================================================ 

END SUBROUTINE READ_IT_PSI 


SUBROUTINE WRITE_IT_PSI(it, psi_E1E2) 
    IMPLICIT NONE 
    !//////////////////////////////////////////////////////////////////////////////// 
    INTEGER        :: it  ! 
    COMPLEX(kind=d_t), DIMENSION(n_phi,n_rho1_seg,n_phi,n_rho2_seg) :: psi_E1E2 ! 
    !================================================================================ 

    integer :: c 

    do c = 0, c_max-1 
     if(mod(iproc,c_max)==c) then 
      !//////////////////////////////////////////////////////////////////////////////// 
      OPEN(unit=11,file=concat(trim(IntermedWaveDir),concat(concat('wave_',str_iproc),'_2p2p2')),& 
             form='unformatted') ! 
       WRITE(11) it+1   !---- recommence a partir de la prochaine iterat! 
       write(11) psi_E1E2       ! 
      CLOSE(11)         ! 
     endif 

     CALL MPI_BARRIER(MPI_COMM_WORLD,infompi)     ! 
     !================================================================================ 
    enddo 

END SUBROUTINE WRITE_IT_PSI 


END MODULE mod_save_wave 
+0

您可能需要鏈接一些Fortran庫。 – 2013-03-21 20:40:19

+0

其實我使用Fortran程序的make文件把所有obj的靜態庫重用它,當我編譯我的C++程序,並在他的make文件不存在的extern LIB – user2196748 2013-03-21 21:29:08

回答

3

我假設你使用的是G ++,gfortran,mpif90工具鏈。如果你有一個模塊

module rocker 
contains 
subroutine bye_baby 
... 
end subroutine 

在C++中它的外部C聲明

extern "C" 
{ 
    //   ,-- 2 Leading underscores to start 
    //   | ,-- then the module name 
    //   | |  ,-- then _MOD_ 
    //   | |  | ,-- then the subroutine name 
    //   V V  V V 
    extern void __rocker_MOD_bye_baby(); 
} 

您可能還需要將extern後加入屬性((STDCALL))。默認情況下,C假定cdecl以不同方式堆疊參數。

1

首先,在Fortran方面,我強烈建議使用C-bindings的Fortran 2003功能,尤其是iso_c_binding模塊。你可以在SO上看到很多例子this post。然後,以透明和獨立於編譯器的方式擺脫「我的fortran編譯器如何命名我的過程」問題。

的連接問題棱因爲你缺少你Fortran編譯的一些圖書館,我猜。您可以嘗試使用Fortran編譯器鏈接您的目標文件,或者找出丟失了哪個庫並手動鏈接它。某些Fortran編譯器還提供了用於創建具有編譯器相關庫的自動鏈接庫的選項。

+0

的frotran程序不是我的,因爲我之前說的所以我不能從FORTRAN90移到2003 Fortran和我想的是注意闡明他的make文件,他使用 mpif90 -c * .F90 -fpp -Dschema = 3 -Dleft_dec_rho = 0.5d0 -Dright_dec_rho = 0.d0 -Dc_max = 6 當我嘗試使用-fpp選項時,出現錯誤:無法識別的命令行選項「fpp」 – user2196748 2013-03-22 15:27:29