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

Python3 ctypes 实现将指针数据复制到自定义Structure结构体的通用方法

实现方法

你可以用ctypes原生的内存操作能力完成需求,以下是两种常用实现方案,还可以封装为通用方法适配所有自定义Structure类型:

方案1:内存拷贝(推荐,生成独立实例不影响原数据)

用ctypes.memcpy直接把Message.data指向的内存内容拷贝到目标结构体实例的地址,提前加长度校验避免内存越界:

# 先导入所需的ctypes工具函数
from ctypes import sizeof, memcpy, addressof

# 长度校验
if p.msg.data_len < sizeof(EventID):
    raise ValueError(f"数据长度不足:目标结构体需要{sizeof(EventID)}字节,实际仅返回{p.msg.data_len}字节")

# 执行拷贝
eid = EventID()
memcpy(addressof(eid), p.msg.data, sizeof(eid))

拷贝完成后可以直接访问eid的字段验证结果:

print([hex(b) for b in eid.recent_addition_timestamp])
# 输出 ['0x88', '0x29', '0xfd', '0x60'],和采样数据完全匹配

方案2:指针强制转换(无额外拷贝,适合只读场景)

如果不需要独立的结构体副本,只是要读取数据,可以直接把c_uint8类型的指针强制转为目标结构体类型的指针,直接读取内容即可:

from ctypes import cast, POINTER

eid = cast(p.msg.data, POINTER(EventID)).contents

注意:该方案得到的eid直接指向原p.msg.data的内存地址,修改eid的字段会同步改动原data的内容,不需要修改原数据的场景优先用方案1。

通用方法封装

可以把以上逻辑封装为通用函数,适配任意自定义Structure类型:

from ctypes import sizeof, memcpy, addressof, cast, POINTER

def buffer_to_struct(data_ptr, data_len, target_struct, copy_mode:bool = True):
    """
    将uint8指针指向的二进制数据转为自定义Structure实例
    :param data_ptr: POINTER(c_uint8) 类型的数据源指针
    :param data_len: 数据源实际有效长度
    :param target_struct: 目标Structure类(注意是类不是实例)
    :param copy_mode: 是否拷贝内存,True返回独立副本,False直接复用原内存
    """
    required_size = sizeof(target_struct)
    if data_len < required_size:
        raise ValueError(f"数据长度不足,目标结构体需要{required_size}字节,实际仅{data_len}字节")
    if copy_mode:
        inst = target_struct()
        memcpy(addressof(inst), data_ptr, required_size)
        return inst
    else:
        return cast(data_ptr, POINTER(target_struct)).contents

调用示例:

# 拷贝副本模式
eid = buffer_to_struct(p.msg.data, p.msg.data_len, EventID)
# 复用原内存模式
eid_ref = buffer_to_struct(p.msg.data, p.msg.data_len, EventID, copy_mode=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 04:57:03