how to call a Fortran90 function included in a module in c++ code?(如何在 C++ 代码中调用模块中包含的 Fortran90 函数?)
问题描述
我在我的 C++ 项目中包含了一个不是我的 fortran90 程序.
I m including a fortran90 program that is not mine in my C++ project .
在第一步中,我尝试通过他们的 name_() 调用该函数,并且通过显示 obj 文件的符号(使用 nm)我发现该函数是由他们的模块作为 module_function_ 所以我添加了模块名称,但在 fortran obj 之间遇到了同样的问题,例如Constants.f90:(.text+0x36): undefined reference to __powi4i4"
In the first stept I try to call the function by their name_() and i get the error "undefined reference to mp_mpi_cartesian_init_ "by dispalying the symbol of the obj file (using nm) i found that the function are called by their module as module_function_ so i add the module name and i Get the same problem but between fortran obj such as "Constants.f90:(.text+0x36): undefined reference to __powi4i4"
这里是 C++ 代码:
here is the c++ code :
 #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
";
     mod_save_wave_mp_read_it_psi_(&it,psi_local);
     cout << "psi ="<< psi_local[0] << "poiur le proc "<<mod_mpl_h_mp_iproc_ <<"
";
   }
这是一个模块的例子:
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 工具链.如果你有一个模块
I am assuming you are using the g++, gfortran, mpif90 toolchain. If you have a module
module rocker
contains
subroutine bye_baby
...
end subroutine
它在 C++ 中的外部 C 声明是
The external C declaration for it in C++ is
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 以不同的方式堆叠参数.
You may also need to add attribute((stdcall)) after the extern. By default, C assumes cdecl which stacks the parameters differently.
如果您不想要 __rocker_MOD 部分,则不应在模块中声明子程序/函数.
If you do not want the __rocker_MOD part, then the subroutine/function should not be declared in a module.
这篇关于如何在 C++ 代码中调用模块中包含的 Fortran90 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在 C++ 代码中调用模块中包含的 Fortran90 函数?
				
        
 
            
        - 与 int by int 相比,为什么执行 float by float 矩阵乘法更快? 2021-01-01
 - 如何对自定义类的向量使用std::find()? 2022-11-07
 - C++ 协变模板 2021-01-01
 - 静态初始化顺序失败 2022-01-01
 - 近似搜索的工作原理 2021-01-01
 - 从python回调到c++的选项 2022-11-16
 - 一起使用 MPI 和 OpenCV 时出现分段错误 2022-01-01
 - 使用/clr 时出现 LNK2022 错误 2022-01-01
 - Stroustrup 的 Simple_window.h 2022-01-01
 - STL 中有 dereference_iterator 吗? 2022-01-01
 
						
						
						
						
						
				
				
				
				