gpt4 book ai didi

c++ - 如何在 C++ 代码中调用模块中包含的 Fortran90 函数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:25:24 25 4
gpt4 key购买 nike

我在我的 C++ 项目中包含了一个不是我的 fortran90 程序。

在第一步中,我尝试通过它们的名称_() 调用该函数,但通过显示 obj 文件的符号(使用 nm)我得到错误“对 mp_mpi_cartesian_init_ 的 undefined reference ”,我发现该函数是由它们调用的模块作为 module_function_ 所以我添加了模块名称并且我得到了同样的问题但是在 fortran obj 之间,例如“Constants.f90:(.text+0x36): undefined reference to __powi4i4”

这是 C++ 代码:

 #include <iostream>
#include <complex>


using namespace std;

extern"C" {

void mod_save_wave_mp_read_it_psi_(int * it,complex<double>* psi_E1E2 );
void mod_mpi_cartesian_mp_mpi_cartesian_init_( );
extern int mod_mpl_h_mp_iproc_ ;
}

int main(){
complex<double> psi_local[512*24*512*24];
int it ;
mod_mpi_cartesian_mp_mpi_cartesian_init_();
cout << "proc :" << mod_mpl_h_mp_iproc_ << "avant lecture\n";
mod_save_wave_mp_read_it_psi_(&it,psi_local);
cout << "psi ="<< psi_local[0] << "poiur le proc "<<mod_mpl_h_mp_iproc_ <<"\n";
}

这是一个模块的例子:

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

最佳答案

我假设您使用的是 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 之后添加 attribute((stdcall))。默认情况下,C 假定 cdecl 以不同方式堆叠参数。

如果您不想要 __rocker_MOD 部分,则不应在模块中声明子例程/函数。

关于c++ - 如何在 C++ 代码中调用模块中包含的 Fortran90 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15557439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com