在Python中使用ctypes将内存映射到结构

问题描述 投票:0回答:1

我正在尝试将内存映射到结构中,但无法获得所需的结果。我的记忆是 32 位值的列表,即

[0x7E008000, 0x1234AAAA, 0xBBBBFFFF]

我正在尝试获得这个输出。

ns: 0x7d008000
us: 0x1234
zs: 0xaaaabbbb
crc: 0xffff

使用以下代码,我没有获得正确的“zs”值,如果我启用“crc”字段,我会收到错误。 这是下面提到的代码的输出

> ns: 0x7d008000
> us: 0x1234
> zs: 0xbbbbffff

这是代码

   import struct
import ctypes

class MemoryParser:
    @classmethod
    def parse_memory(cls, memory):
        memory_bytes = bytearray()

        for word in memory:
            # Convert the word to little-endian bytes
            word_bytes = struct.pack(">I", word)
            # Extend memory_bytes with the word bytes in little-endian order
            memory_bytes.extend(word_bytes)

        # Create a ctypes pointer from the memory_bytes
        ubuffer = (ctypes.c_ubyte * len(memory_bytes)).from_buffer(memory_bytes)

        # Return the class instance created from the ctypes pointer
        return cls.from_buffer(ubuffer)

class Data(MemoryParser, ctypes.BigEndianStructure):
    _fields_ = [("ns", ctypes.c_uint32),
                ("us", ctypes.c_uint16),
                ("zs", ctypes.c_uint32)]
                #("crc", ctypes.c_uint16)]

memory = [0x7E008000, 0x1234AAAA, 0xBBBBFFFF]

data = Data.parse_memory(memory)

print("ns:", hex(data.ns))
print("us:", hex(data.us))
print("zs:", hex(data.zs))
#print("crc:", hex(data.crc))

更新1:

因此我收集了另一个数据集并创建了字段,但它再次失败。

数据集,示例

[0x7E008000, 0x1234AAAA, 0xBBBBFFFC, 0xCCCDDEEE]

预期数据的新类字段结构是什么

v1 = 0x7E008000
v2 = 0x1234
v3 = 0xAAAABBBB
v4 = 0xFFF
v5 = 0xCCCC
v6 = 0xDD
v7 = 0xEEEE
python ctypes
1个回答
0
投票

ctypes 遵循结构体中元素对齐的 C 规则。出于效率原因,例如32 位(4 字节)整数的第一个字节位于可被 4 整除的地址处。为了避免额外的填充字节以实现正确对齐,请将

_pack_ = 1
添加到 ctypes 结构中(请参阅 文档),如下所示:

class Data(MemoryParser, ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [("ns", ctypes.c_uint32),
                ("us", ctypes.c_uint16),
                ("zs", ctypes.c_uint32),
                ("crc", ctypes.c_uint16)]

出现

crc
字段的错误是因为由于 4 个填充字节,原始结构的大小为 16 字节,而原始输入只有 12 字节。

© www.soinside.com 2019 - 2024. All rights reserved.