如何通过iso_c_binding将C中malloc的28返回至Fortran?
问题:如何将数值28从C端返回至Fortran端?
原代码运行后,Fortran端的指针始终为0,无法获取C端设置的28,核心原因是C函数没有正确修改Fortran传入的指针变量。以下是无需结构体的简便修正方案:
问题根源
原C函数roll_dice_的参数是int *test,这里修改的是函数内部的局部指针变量,并不会影响Fortran端传入的test_ptr。要让Fortran获取到C端malloc的内存地址,C函数需要接收指针的指针(int **test),这样才能把新分配的内存地址传递回Fortran。
修正后的代码
1. C端(test.c)
#include <stdio.h> #include <stdlib.h> int roll_dice_(int **test) { if (*test == NULL) { printf("Creating storage for test\n"); *test = malloc(sizeof(int)); **test = 28; printf("variable test is set to %d\n\n", **test); } else { printf("test is not null\n"); } return 0; }
2. Fortran接口(play_dice_game.f90)
保持参数类型为c_ptr,兼容C端的指针传递:
module play_dice_game use, intrinsic :: iso_c_binding, only: c_int, c_ptr interface function roll_dice(test_p) bind(c, name="roll_dice_") import :: c_int, c_ptr implicit none type(c_ptr), intent(out) :: test_p integer(c_int) :: roll_dice end function end interface end module play_dice_game
3. Fortran主程序(main.f90)
无需修改原逻辑:
program test use play_dice_game use iso_c_binding, only : c_ptr, c_f_pointer, c_null_ptr type(c_ptr) :: test_ptr integer, pointer :: ftest_ptr integer result test_ptr = c_null_ptr result = roll_dice(test_ptr) call c_f_pointer(test_ptr, ftest_ptr) write(*,*) 'C test pointer is ',test_ptr write(*,*) 'Fortran test pointer is ',ftest_ptr end program test
编译运行步骤
gcc -g -c test.c -o test.o gfortran -g -c play_dice_game.f90 -o play_dice_game.o gfortran -g -c main.f90 -o main.o gfortran -g main.o test.o -o main.exe -lgfortran ./main.exe
预期运行输出
Creating storage for test variable test is set to 28 C test pointer is 0x55... # 实际内存地址 Fortran test pointer is 28
说明
- C端通过
int **test接收Fortran的c_ptr,修改*test的值即可将malloc的内存地址传递回Fortran; c_f_pointer负责将C指针(c_ptr)转换为Fortran可关联指针,直接访问C端设置的数值;- 该方案比结构体实现更简洁,无需额外定义复合类型。
内容的提问来源于stack exchange,提问作者giraffe
相关产品推荐
相关产品推荐

