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

Python ctypes深拷贝Structure结构体报错TypeError,求正确实现

问题分析与修正

你的代码报错TypeError: invalid type,核心问题出在数组创建和内存管理上,具体修正如下:

错误原因

  1. 创建数组时,直接使用c_uint32类型的实例作为数组大小,ctypes要求此处必须是Python原生整数,需先做类型转换。
  2. 仅定义了数组类型但未实例化,导致addressof无法获取有效内存地址。
  3. 局部数组对象会在函数结束后被垃圾回收,拷贝后的指针会变成无效野指针。

修正后的深拷贝实现

from ctypes import *

class Group(Structure):
    _fields_ = [
        ("ChSize", c_uint32*9),
        ("DataChannel", POINTER(c_float)*9),
        ("TriggerTimeLag", c_uint32),
        ("StartIndexCell", c_uint16)]
    
    def deepcopy(self):
        copy = Group()
        # 保存拷贝的数组对象,防止被垃圾回收
        copy._buffers = []
        # 拷贝简单字段(无需循环重复赋值)
        copy.TriggerTimeLag = self.TriggerTimeLag
        copy.StartIndexCell = self.StartIndexCell
        
        for n_channel in range(9):
            size = int(self.ChSize[n_channel])
            copy.ChSize[n_channel] = self.ChSize[n_channel]
            
            if size == 0:
                copy.DataChannel[n_channel] = None
                continue
            
            # 实例化对应大小的float数组,分配实际内存
            data_buffer = (c_float * size)()
            # 拷贝原数据到新数组
            memmove(data_buffer, self.DataChannel[n_channel], size * sizeof(c_float))
            # 将数组转为float指针赋值给拷贝对象
            copy.DataChannel[n_channel] = cast(data_buffer, POINTER(c_float))
            # 保存数组引用,避免被GC回收导致指针失效
            copy._buffers.append(data_buffer)
        
        return copy

关键修正点

  • 将self.ChSize[n_channel]转为Python整数int(...)后再创建数组类型。
  • 实例化数组对象(c_float * size)(),分配实际内存空间。
  • 新增_buffers属性保存数组实例,防止函数结束后数组被垃圾回收。
  • 把简单字段的拷贝移到循环外,避免重复赋值。
  • 增加size为0的判断,避免空指针操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:37:26