首页 > 解决方案 > 如何使用 ctypes 读取多字节值

问题描述

我想使用 ctypes Structure 和 Union 从字节对象中读取两个连续的 24 位值。这将是 6 个字节。

不幸的是,ctypes 每个值读取 32 位。此外,sizeof报告结构比预期的要大。

使用_pack_ = 1并没有带来预期的结果。

具有最小结构和二进制示例值的示例:

import unittest
import ctypes

SixBytes = ctypes.c_uint8 * 6

class MultiBits(ctypes.BigEndianStructure):
    _pack_ = 1
    _fields_ = [
        ("x", ctypes.c_uint, 24),
        ("y", ctypes.c_uint, 24),
    ]

class Multi(ctypes.Union):
    _fields_ = [
        ("bits", MultiBits),
        ("asbytes", SixBytes),
    ]

class TestMultibyte(unittest.TestCase):
    def test_size(self):
        self.assertEqual(ctypes.sizeof(MultiBits), 6)

    def test_multibyte(self):
        data = b'\x00\x01\x01\x00\x01\x02'
        parser = Multi()
        parser.asbytes = SixBytes(*data)
        self.assertEqual(parser.bits.x, 257)
        self.assertEqual(parser.bits.y, 258)

我本来希望sizeof(MultiBits)6正确解析的值。

相反,sizeof(MultiBits)报告为预期结果的 256 倍8parser.bits.y

我是在做错事还是期待错事?

标签: pythonstructctypes

解决方案


您可以一次int.from_bytes解码 24 位(3 个字节)。

data = b'\x00\x01\x01\x00\x01\x02'
[int.from_bytes(data[i:i+3], byteorder='little', signed=False) for i in range(0, len(data), 3)]
>>> [65792, 131328]

整数在您的代码中是无符号的,我猜测字节顺序是小端,尽管看起来您的测试假设是大端。


推荐阅读