C++与Fortran结构体映射:改用std::vector后结构不匹配的问题
C++ std::vector与Fortran结构体的匹配解决方案
问题背景
原项目已实现C指针数组结构体与Fortran指针结构体的双向映射,现C侧改用std::vector<double>(别名CDArray)后,Fortran侧结构体无法匹配,需调整实现方式。
核心问题
std::vector是C++容器,内部包含指针、大小、容量等成员,和单纯的double*内存布局完全不同,直接用原Fortran指针结构体无法匹配内存结构,必须通过std::vector::data()获取底层数组指针来对接Fortran。
解决方法
方案一:临时封装指针结构体用于跨语言调用(推荐)
C++侧保留原指针版结构体做跨语言对接,调用时将std::vector的底层指针传入临时结构体:
// 保留原指针版结构体用于对接Fortran struct t_res_p_c { double *p_length = nullptr; double *p_diam = nullptr; }; // 现有含std::vector的业务结构体 struct t_res_p { CDArray p_length; CDArray p_diam; }; // 调用Fortran子例程的适配代码 t_res_p p_res; p_res.p_length.SetSize(ns, 0.0); p_res.p_diam.SetSize(ns, 0.0); t_res_p_c temp_p; temp_p.p_length = p_res.p_length.data(); temp_p.p_diam = p_res.p_diam.data(); p_model(&temp_p); // 传递临时指针结构体给Fortran
Fortran侧保持原t_res_p_ext结构体和子例程定义不变,直接操作指针指向的数组即可。
方案二:修改Fortran结构体对接std::vector内存布局(不推荐)
若必须直接传递含std::vector的结构体,需依赖特定编译器的std::vector内存布局(可移植性低),Fortran侧定义对应结构体:
use, intrinsic :: iso_c_binding type, bind(C) :: CDArray_ext sequence real(8), pointer :: data_ptr integer(C_SIZE_T) :: size integer(C_SIZE_T) :: capacity end type CDArray_ext type, bind(C) :: t_res_p_ext sequence type(CDArray_ext) :: p_length type(CDArray_ext) :: p_diam end type t_res_p_ext subroutine p_model(p_res) bind(C) type(t_res_p_ext), intent(inout) :: p_res ! 通过p_res%p_length%data_ptr访问数组 ! 注意:禁止修改size/capacity字段,否则会破坏C++容器内部状态 end subroutine p_model
总结
优先选择方案一,通过临时指针结构体做适配,既保留C++侧使用std::vector的便利性,又兼容原Fortran实现,避免内存布局依赖带来的可移植性问题。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

