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

从C向Fortran子例程传递未知长度数组失败,如何无长度指定传递?

Fortran与C交互:动态传递数组无需指定固定长度的解决方案

问题背景

你编写的Fortran子例程通过bind(c)与C主程序交互,当使用假定形状数组(integer(c_int) a(:))时,打印数组会失败;但将数组声明改为固定长度(a(5))则能正常运行。核心需求是实现无需硬编码数组长度,即可在Fortran中正确处理来自C的数组。

根本原因

C语言仅传递数组的首地址,不会附带数组的长度、形状等元数据;而Fortran的假定形状数组依赖内部的*描述符(descriptor)*来解析数组结构,缺少这个描述符时,Fortran无法正确识别数组的边界,进而导致运行错误。固定长度数组不需要描述符,直接按首地址+固定长度访问内存,因此可以正常工作。

可行解决方案

1. 显式传递数组长度(最直接可靠的方式)

在C调用时额外传递数组长度,Fortran子例程用该长度定义显式形状数组,即可正常操作数组。

修改后的Fortran子例程:

subroutine my_subroutine(a, b, arr_len) bind(c, name='my_subroutine')
    use iso_c_binding
    implicit none
    integer(c_int), intent(in) :: arr_len
    integer(c_int), intent(in) :: a(arr_len)
    real(c_double), intent(in) :: b(arr_len)

    print *, "Printing from Fortran subroutine:"
    print *, "Array a content:"
    print *, a
    print *, "Array b content:"
    print *, b
end subroutine my_subroutine

对应的C主程序:

#include <stdlib.h>

void my_subroutine(int *, double *, int);

int main()
{
    const int arr_len = 5;
    int *a = calloc(arr_len, sizeof(int));
    double *b = calloc(arr_len, sizeof(double));

    for (int i = 0; i < arr_len; i++)
    {
        a[i] = i;
        b[i] = i;
    }

    my_subroutine(a, b, arr_len);

    free(a);
    free(b);

    return EXIT_SUCCESS;
}

2. 使用c_ptr与c_f_pointer转换(灵活处理动态数组)

先接收C传递的指针,再通过Fortran的c_f_pointer函数将其关联到假定形状数组,同样需要传递数组长度来指定形状。

Fortran子例程示例:

subroutine my_subroutine(a_ptr, b_ptr, arr_len) bind(c, name='my_subroutine')
    use iso_c_binding
    implicit none
    type(c_ptr), intent(in) :: a_ptr, b_ptr
    integer(c_int), intent(in) :: arr_len
    integer(c_int), pointer :: a(:)
    real(c_double), pointer :: b(:)

    ! 将C指针关联到Fortran假定形状数组
    call c_f_pointer(a_ptr, a, [arr_len])
    call c_f_pointer(b_ptr, b, [arr_len])

    print *, "Printing from Fortran subroutine:"
    print *, a
    print *, b
end subroutine my_subroutine

C主程序修改与第一种方法一致,需传递arr_len参数。

3. 假定大小数组(不推荐,仅兼容旧代码)

可以用integer(c_int) a(*)声明假定大小数组,此时Fortran不检查数组边界,但打印整个数组仍需知道长度,且存在越界访问风险,不建议在新代码中使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:33:25