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

Python C扩展传递整数数组异常:调用C++共享库返回值错误排查

问题排查与解决

核心问题

你的C++函数call_my_routine里的循环终止逻辑出错了:array[i]!='\0'这里的'\0'是字符字面量,对应整数值0,但你传递的Python列表里没有0元素,而且ctypes创建的数组后面的内存区域可能存在非0数据,导致循环越界读取,直到偶然碰到内存里的0才停止,所以返回了错误的17。

解决方案

有两种可靠的修正方式:

方式1:给数组加终止符0

修改Python代码,在列表末尾补个0,让C函数能正确识别数组结束:

# test.py
from ctypes import CDLL, c_int

so_file = "./libtest.so"

my_function = CDLL(so_file)

py_list = [2,3,5,7,4,12,21,49, 0]  # 添加终止符0
array = (c_int * len(py_list))(*py_list)

print(my_function.call_my_routine(array))

C++代码不用改,此时循环会在遇到0时终止,返回正确的8。

方式2:传递数组长度给C函数(更推荐)

这是C/C++处理数组的标准做法,不需要依赖终止符:

  1. 修改C++代码,新增长度参数:
// test.cc
    
extern "C" {

    int call_my_routine(int *array, int length) {
        int count = 0;
        for(int i=0; i < length; i++)
        {
            count++;
        }
        return count;
    }
}
  1. 修改Python代码,传递数组长度:
# test.py
from ctypes import CDLL, c_int

so_file = "./libtest.so"

my_function = CDLL(so_file)
# 显式指定函数参数和返回值类型(可选但推荐,避免类型错误)
my_function.call_my_routine.argtypes = [c_int, c_int]
my_function.call_my_routine.restype = c_int

py_list = [2,3,5,7,4,12,21,49]
array = (c_int * len(py_list))(*py_list)

print(my_function.call_my_routine(array, len(py_list)))

重新编译共享库后,运行就能得到正确的8。

额外提醒

  • C/C++里单独传递数组时,无法直接获取数组长度,要么靠终止符(比如字符串的'\0'),要么额外传长度参数。
  • 显式指定argtypes和restype能避免ctypes自动类型转换的潜在问题,调用C函数时建议都加上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:51:03