You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:35:20