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

从C回调Fortran函数:非互操作参数的实现方法

Fortran与C回调中传递非互操作派生类型的实现方案

完全可行。因为C层仅负责透传params的地址,不需要解析其内部结构,只要保证地址传递的正确性,Fortran端就能完成类型的正确映射。以下是具体实现步骤:

一、Fortran中声明callback_from_c的互操作接口

需要借助iso_c_binding模块,匹配C侧的函数指针和函数签名:

use, intrinsic :: iso_c_binding

! 定义对应C中callback_func_t的Fortran函数指针类型
type, bind(c) :: callback_func_t
  procedure(c_func), pointer, nopass :: func => null()
end type callback_func_t

! 抽象接口,匹配C回调函数的签名
abstract interface
  function c_func(params) bind(c)
    import :: c_ptr
    integer(c_int) :: c_func
    type(c_ptr), value :: params
  end function c_func
end interface

! 声明C函数callback_from_c的互操作接口
interface
  subroutine callback_from_c(my_fortran_func, params) bind(c, name='callback_from_c')
    import :: callback_func_t, c_ptr
    type(callback_func_t), intent(in), value :: my_fortran_func
    type(c_ptr), value :: params
  end subroutine callback_from_c
end interface

二、定义非互操作派生类型及Fortran回调函数

以一个自定义非互操作类型为例,实现接收透传参数的回调函数:

! 非互操作的Fortran派生类型
type :: my_type
  integer :: id
  real :: value
end type my_type

! Fortran回调函数,将C指针转换回Fortran类型指针
function my_callback(params) bind(c)
  use, intrinsic :: iso_c_binding
  integer(c_int) :: my_callback
  type(c_ptr), value :: params
  type(my_type), pointer :: f_params

  ! 将C指针映射为Fortran类型指针
  call c_f_pointer(params, f_params)

  ! 操作非互操作类型的数据(示例为打印)
  print *, "ID:", f_params%id
  print *, "Value:", f_params%value

  my_callback = 0  ! 返回符合C侧要求的int类型值
end function my_callback

三、调用C函数并传递非互操作类型参数

在主程序中完成地址转换与函数调用:

program main
  use, intrinsic :: iso_c_binding
  type(my_type), target :: my_data  ! 需添加target属性以获取地址
  type(callback_func_t) :: callback_obj
  type(c_ptr) :: c_params

  ! 初始化非互操作类型数据
  my_data%id = 123
  my_data%value = 3.14

  ! 将Fortran变量地址转为C兼容指针
  c_params = c_loc(my_data)

  ! 绑定回调函数到函数指针对象
  callback_obj%func => my_callback

  ! 调用C侧函数
  call callback_from_c(callback_obj, c_params)

end program main

关键注意事项

  • C层仅做地址透传,无需感知params的具体类型,不会触发类型兼容性问题。
  • Fortran侧必须为非互操作类型变量添加target属性,才能通过c_loc获取其地址;回调中需用c_f_pointer将C指针转换回Fortran类型指针。
  • 回调函数的签名必须严格匹配C侧定义:返回integer(c_int)类型,参数为type(c_ptr), value。

内容的提问来源于stack exchange,提问作者booNlatoT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 11:35:18