C++与Fortran(F90)跨语言数据传递问题及编译错误求助
问题:Fortran与C++交互时结构体指针转换错误及数据失效问题
更新说明
已按建议将psubstuff改为c_ptr,并通过c_f_pointer访问bstuff,这部分操作成功。但因实际代码需要第二个成员为t_bstuff的t_stuff结构体,故创建了t_stuff的副本(绑定C的版本命名为t_stuff_c),尝试将t_stuff_c的内容复制到t_stuff时出现编译错误:
error #6285: There is no matching specific subroutine for this generic subroutine call. [C_F_POINTER]
背景情况
C++主程序调用Fortran DLL中的函数,已简化为示例代码复现问题:
- C程序创建
t_stuff类型变量stuff,其包含char数组name和void*类型成员substuff(因Fortran侧substuff结构复杂,无需在C侧定义)。 - 调用Fortran的
crfl()函数在Fortran侧创建substuff。 - 调用Fortran的
stfl()函数将字符"TEST"写入substuff%clb%corf,调试显示此时该值正确。 - 调用Fortran的
test2()函数传入stuff后,调试发现stuff%substuff%clb%corf值变为垃圾数据,但stuff的name成员值正确。
完整代码
C++代码
#include <iostream> #include <cstddef> #include <vector> using namespace std; struct t_stuff { char name[256]; void *substuff; }; //Fortran subroutine definitions extern "C" { void test2(t_stuff *stuff); } extern "C" { void * crfl(); int stfl(void * cstuff, char * name); } int main() { int ierr; t_stuff *stuff; stuff = new t_stuff; strcpy_s((*stuff).name, sizeof((*stuff).name), "ACF-C"); (*stuff).substuff = crfl(); ierr = stfl((*stuff).substuff, "TEST"); test2(stuff); }
Fortran代码
module ftncode_mod use, intrinsic :: iso_c_binding implicit none type, public :: t_clb character(8) :: corf end type type, public :: t_bstuff type (t_clb) :: clb end type t_bstuff type, public, bind(C) :: t_stuff_c character(1) :: name(256) type (c_ptr) :: psubstuff end type t_stuff_c type, public :: t_stuff character :: name(256) = ' ' type (t_bstuff) :: psubstuff end type t_stuff contains subroutine c2fstr(cptr,fstr) type(c_ptr), value, intent(in ) :: cptr character(*), intent(out) :: fstr character(256), pointer :: lfstr integer :: id call c_f_pointer(cptr,lfstr) id = index(lfstr,c_null_char)-1 if(id.le.0) id=len(lfstr) fstr = lfstr(1:id) end subroutine function crfl() result(cp) bind(C) !DEC$ ATTRIBUTES DLLEXPORT :: crfl type(c_ptr ) :: cp type(t_bstuff), pointer :: fp allocate(fp) cp = c_loc(fp) end function function stfl(cstuff,cne) result(ierr) bind(C) !DEC$ Attributes dllexport :: stfl type(c_ptr), value, intent(in) :: cstuff type(c_ptr), value, intent(in) :: cne integer :: ierr type(t_bstuff) , pointer :: fstuff character(24) :: cwk ierr = 0 call c_f_pointer(cstuff,fstuff) call c2fstr(cne,cwk) fstuff%clb%corf = trim(cwk) end function subroutine test2(stuff) bind(C) !DEC$ATTRIBUTES DLLEXPORT :: test2 use iso_c_binding type(t_stuff_c), target, intent(in) :: stuff type(t_stuff) :: fstuff type(t_bstuff), pointer :: bstuff integer :: i call c_f_pointer(stuff%psubstuff,bstuff) print *, "stuff%substuff%clb%corf: ", bstuff%clb%corf ! correct ! now need to populate the derived Fortran structure, fstuff do i = 1, 256 if(stuff%name(i) == c_null_char) exit fstuff%name(i:i) = stuff%name(i) enddo ! and the pointer call c_f_pointer(stuff,fstuff) print *, "fstuff%substuff%clb%corf: ", fstuff%psubstuff%clb%corf end subroutine test2 end module
需求
寻求解决上述指针失效及编译错误的方案。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

