从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
相关产品推荐
相关产品推荐

