2013-03-21 2 views
2

내 C++ 프로젝트에있는 fortran90 프로그램이 포함되어 있습니다.C++ 코드로 모듈에 포함 된 Fortran90 함수를 호출하는 방법은 무엇입니까?

첫 번째 stept 나는 그들의 name_() 함수를 호출하려고 및 nm "사용하여 obj 파일의 기호를 dispalying하여"mp_mpi_cartesian_init_ "정의되지 않은 참조 오류가 발생합니다 module_function_ 않도록 자신의 모듈은 내가 모듈 이름을 추가하고 내가 같은 동일한 문제가 있지만, 포트란 (OBJ) 사이를 받기 : 여기

는 C++ 코드 "Constants.f90 :(텍스트 + 0x36) __powi4i4에 정의되지 않은 참조."

이는 모듈의 exemple이다

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 라이브러리와 링크해야합니다. –

+0

실제로 Fortran 프로그램의 make 파일을 사용하여 모든 obj를 정적 라이브러리에 넣어서 C++ 프로그램을 컴파일하고 파일을 만들 때 extern lib가 없습니다 – user2196748

답변

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(); 
} 

당신은 또한 통근 후 속성 ((stdcall을))를 추가해야 할 수도 있습니다. 기본적으로 C는 매개 변수를 다르게 스택하는 cdecl을 가정합니다.

1

우선 포트란 측에서 C 바인딩의 Fortran 2003 기능, 특히 iso_c_binding 모듈을 사용하는 것이 좋습니다. SO에 대한 많은 예를 볼 수 있습니다. 다른 예로는 this post입니다. 그렇다면 "fortran 컴파일러가 내 프로 시저를 어떻게 이름 짓는가"라는 문제를 투명하고 컴파일러 독립적 인 방식으로 제거 할 수 있습니다.

Fortran 컴파일러의 일부 라이브러리가 누락되어 링크 문제가 발생합니다. Fortran 컴파일러를 사용하여 오브젝트 파일을 링크하거나 누락 된 라이브러리를 찾아 수동으로 링크 할 수 있습니다. 일부 Fortran 컴파일러에는 컴파일러 관련 라이브러리의 자동 링크를 사용하여 라이브러리를 생성하는 옵션도 있습니다.

+0

frotran 프로그램은 전에 말했던 것처럼 광산이 아닙니다 그래서 Fortran90에서 Fortran 2003으로 옮길 수 없다. 나는 그의 make 파일에서 그가 사용하는 파일을 mpif90 -c * .f90 -fpp -Dschema = 3 -Dleft_dec_rho = 0.5d0 -Dright_dec_rho = 0.d0 -Dc_max = 6 이 옵션을 -fpp 옵션으로 사용하면 오류가 발생합니다. 인식 할 수없는 명령 행 옵션 -a-fpp – user2196748

관련 문제