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

Fortran与C/C++混合编程:链接错误及数组传递异常求助

解决Fortran与C混合编程中动态数组传递的问题

你已经搞定了链接阶段的小问题(把-lg fortran改成-lgfortran确实是正确操作),但核心问题出在Fortran代码的数组指针处理逻辑上,咱们一步步理清楚:

问题分析

你的需求是在Fortran中动态分配数组,再把这个数组的地址传递给C程序,但当前Fortran代码里的c_f_pointer用法完全搞反了:c_f_pointer的作用是把C风格指针转换成Fortran可识别的指针,而非把Fortran指针传给C。另外代码里还有语法错误:=>b这行是无效的,完全没必要写这一步。

现在的逻辑是试图把传入的C指针(outp)绑定到Fortran指针a上,导致C程序拿到的是随机内存地址,自然输出乱码。

修正后的代码

修正后的Fortran代码

subroutine test_allocation(outp) bind(c)
    use iso_c_binding
    implicit none
    type(c_ptr), intent(out) :: outp  ! 明确为输出参数
    integer(c_int), pointer :: a(:)
    
    ! 动态分配数组并赋值
    allocate(a(2))
    a(1) = 1
    a(2) = 2
    
    ! 获取Fortran指针的C风格地址,传递给C程序
    outp = c_loc(a)
    
    print*, "a(1) in Fortran: ", a(1)
    print*, "a(2) in Fortran: ", a(2)
    print*, "outp (C pointer address): ", outp
end subroutine

修正后的C代码

C代码核心逻辑没问题,但建议补充内存释放的逻辑(Fortran分配的数组必须由Fortran释放):

#include <iostream>
using namespace std;

extern "C" void test_allocation(int** ptr);
// 新增释放数组的Fortran子例程声明,避免内存泄漏
extern "C" void free_fortran_array(int** ptr);

int main () {
    int* ptr = nullptr;
    test_allocation(&ptr);
    
    cout<<"ptr[0] in C: "<< ptr[0]<<endl;
    cout<<"ptr[1] in C: "<< ptr[1]<<endl;
    
    // 调用Fortran的释放函数
    free_fortran_array(&ptr);
    return 0;
}

可选:内存释放的Fortran子例程

subroutine free_fortran_array(arr_ptr) bind(c)
    use iso_c_binding
    implicit none
    type(c_ptr), intent(inout) :: arr_ptr
    integer(c_int), pointer :: a(:)
    
    ! 先将C指针转回Fortran指针
    call c_f_pointer(arr_ptr, a, [2])
    deallocate(a)
    ! 将C指针置空,避免野指针
    arr_ptr = c_null_ptr
end subroutine

编译与运行命令

假设Fortran文件名为test.f90,C++文件名为main.cpp,执行以下命令:

# 编译Fortran生成目标文件
gfortran -c test.f90 -o test.o
# 编译C++生成目标文件
g++ -c main.cpp -o main.o
# 链接并生成可执行文件
g++ main.o test.o -lgfortran -o mixed_program
# 运行程序
./mixed_program

预期输出

运行后会得到符合预期的结果(内存地址可能不同,但数值正确):

a(1) in Fortran:  1
 a(2) in Fortran:  2
 outp (C pointer address):  0x55a97c26eb20
ptr[0] in C: 1
ptr[1] in C: 2

额外注意点

  • 类型匹配:必须用integer(c_int)对应C的int,避免不同平台下整数宽度不一致导致的问题。
  • 内存管理:Fortran分配的内存不能用C的free释放,必须由Fortran子例程处理,否则会触发内存错误。
  • bind(c):确保Fortran子例程的命名符合C规则,避免编译器修改函数名导致链接失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:33:10