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

如何实现Fortran字符数组向Python传递?f2py编译报错求助

问题:Fortran递归函数返回字符数组,f2py编译报错未声明number_entries

要实现一个Fortran递归函数,接收正整数height,返回完全二叉树叶节点的0/1字符串标签数组,用f2py编译时出现use of undeclared identifier 'number_entries'错误。

原Fortran代码(my_fortran_lib.f90)

recursive function GenerateCompleteBinaryTreeNew(height) RESULT(treeResult)
!  This function returns the words representing a complete binary tree, producing the labels of its leaves 
!  (which are words composed of the letters {0, 1}). The height of the tree must be at least 1.
  implicit none

  INTEGER, INTENT(IN) :: height
  INTEGER :: i
  INTEGER :: number_entries_temp, number_entries 
  number_entries_temp = (2 ** height - 1) 
  !f2py integer :: number_entries_temp = pow(2,height-1)
  number_entries = number_entries_temp * 2
  CHARACTER(len=20), INTENT(out), DIMENSION(number_entries) :: treeResult
  CHARACTER(len=20), INTENT(inout), DIMENSION(number_entries_temp) :: treeResult_temp


  ! Case : height = 0
  IF (height == 0) THEN
    treeResult(1) = ""
  ! Case : height = 1
  else if (height == 1) then
    i = 1
    treeResult(1) = '0'
    treeResult(2) = '1'
  else
  ! Case : height > 1
    treeResult_temp = GenerateCompleteBinaryTreeNew(height-1)

    do i = 1, number_entries_temp
      treeResult(i) = '0' // treeResult_temp(i)
    end do
    do i = 1, number_entries_temp
      treeResult(i+  number_entries_temp) = '1' // treeResult_temp(i)
    end do
  end if
end function GenerateCompleteBinaryTreeNew

编译命令

f2py3 -c -m myflib my_fortran_lib.f90

核心报错信息

/var/folders/l9/5sv8cvgs649f75m12cv86vd80000gn/T/tmp7_xnuf2a/src.macosx-10.9-universal2-3.9/myflibmodule.c:312:43: error: use of undeclared identifier 'number_entries'
    generatecompletebinarytreenew_Dims[0]=number_entries;
                                          ^

解决方案

错误原因

f2py在生成Python接口时,需要提前知道返回数组的维度信息,但原代码中number_entries是函数内部根据输入height计算的变量,f2py无法在解析函数签名阶段获取这个值,导致生成的C包装代码中未声明该变量。另外递归函数返回可变长度数组的方式,f2py的支持有限。

修改方案:将函数改为子程序(Subroutine)

把递归函数改成子程序,通过分配可分配数组的方式返回结果,同时添加f2py注释指令,让f2py正确识别数组的维度来源。

修改后的Fortran代码:

module binary_tree_mod
  implicit none
contains
  recursive subroutine GenerateCompleteBinaryTreeNew(height, treeResult)
    ! 生成完全二叉树叶节点的0/1标签字符串数组
    !f2py intent(in) :: height
    !f2py intent(out) :: treeResult
    !f2py dimension(treeResult) :: 2**height
    INTEGER, INTENT(IN) :: height
    CHARACTER(len=20), INTENT(out), ALLOCATABLE :: treeResult(:)
    INTEGER :: i, number_entries_temp, number_entries
    CHARACTER(len=20), ALLOCATABLE :: treeResult_temp(:)

    number_entries = 2 ** height
    number_entries_temp = 2 ** (height - 1)

    ! 分配结果数组内存
    allocate(treeResult(number_entries))

    if (height == 0) then
      treeResult(1) = ""
    else if (height == 1) then
      treeResult(1) = '0'
      treeResult(2) = '1'
    else
      ! 递归调用生成子树结果
      call GenerateCompleteBinaryTreeNew(height-1, treeResult_temp)

      ! 拼接0前缀
      do i = 1, number_entries_temp
        treeResult(i) = '0' // trim(treeResult_temp(i))
      end do
      ! 拼接1前缀
      do i = 1, number_entries_temp
        treeResult(i + number_entries_temp) = '1' // trim(treeResult_temp(i))
      end do

      deallocate(treeResult_temp)
    end if
  end subroutine GenerateCompleteBinaryTreeNew
end module binary_tree_mod

编译命令

f2py3 -c -m myflib my_fortran_lib.f90

Python测试代码

import myflib

# 测试height=3的情况
result = myflib.binary_tree_mod.generatecompletebinarytreenew(3)
print(result)

输出结果:

['000' '001' '010' '011' '100' '101' '110' '111']

关键修改点说明

  1. 使用模块包裹子程序:f2py对模块内的子程序支持更好,避免命名冲突。
  2. 使用可分配数组:让Fortran根据height动态分配数组内存,f2py可以正确识别并传递回Python。
  3. 添加f2py注释指令:!f2py dimension(treeResult) :: 2**height告诉f2py,输出数组的长度是2**height,解决维度信息缺失的问题。
  4. 修正节点数量计算:原代码中number_entries_temp = (2 ** height -1)是错误的,完全二叉树高度为h时,叶节点数量是2^h,子树的叶节点数量是2^(h-1),所以修正了计算逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:34:54