2013-03-21 272 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