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

Python ctypes调用C++接口返回字符串数组数据损坏问题排查

问题根因分析
  • C++侧局部对象悬空指针
    你在getStrings函数中使用auto strs = inst->getStrings();接收vector时,因为getStrings返回的是vector引用,不加&的情况下auto会推导为值类型,相当于生成了一个局部vector副本。你将该局部副本的data()指针作为返回值输出,函数执行结束后局部vector被销毁,对应内存空间被回收,你拿到的就是野指针,因此前几个元素出现数据损坏,未被覆盖的后几个元素暂时正常。
  • Python ctypes未声明函数原型
    ctypes默认将所有导出函数的返回值识别为int类型,在64位操作系统中,指针长度为8字节、int长度为4字节,会导致返回的指针地址被截断,也可能引发内存访问异常。
修复方案

1. 修复C++代码

将getStrings函数中的值接收改为引用接收,避免生成局部副本:

void getStrings(void* test_ptr, char*** strings, size_t* length) {
    auto inst = reinterpret_cast<Test *>(test_ptr);
    // 加&用引用接收,不拷贝vector
    auto& strs = inst->getStrings();
    *strings = strs.data();
    *length = strs.size();
}

额外建议:补充对应destroyTest的导出函数,主动释放Test实例避免内存泄漏。

2. 修复Python代码

加载动态库后主动声明导出函数的参数和返回值类型:

from ctypes import *
lib = cdll.LoadLibrary("test.so")

# 声明函数原型
lib.createTest.restype = c_void_p
lib.getStrings.argtypes = [c_void_p, POINTER(POINTER(c_char_p)), POINTER(c_size_t)]

test_ptr = lib.createTest()

strs_arr = POINTER(c_char_p)()
strs_len = c_size_t()

lib.getStrings(test_ptr, byref(strs_arr), byref(strs_len))

for i in range(0, strs_len.value):
    print("var {}: data={}".format(i, strs_arr[i]))
验证效果

修改后重新编译动态库,运行Python代码即可正常输出全部字符串:

var 0: data=b'test1'
var 1: data=b'test2'
var 2: data=b'test3'
var 3: data=b'test4'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:06:02