Python NamedTuple C-struct包解释

cpjpxq1n  于 2023-04-19  发布在  Python
关注(0)|答案(1)|浏览(93)

我有一个如何将C-struct转换为python的多个问题。下面是一个C输入:

struct stE220_Header {
   uint8_t cmd;
   uint8_t startAddr;
   uint8_t length;
};

struct stE220_Cfg {
   struct stE220_Header cmdHeader;

   uint8_t ADDH; // E220_REG_ADDRESS_CFG
   uint8_t ADDL;

   struct stSpeed { // E220_REG_SPEED
      uint8_t airDataRate:3;
      uint8_t uartParity :2;
      uint8_t uartBaudRate:3;
   } speed;
   struct stOption { // E220_REG_TRANS_MODE
      uint8_t transmisstingPower:2;
      uint8_t :3;
      uint8_t RSSIAmbientNoise:1;
      uint8_t subPacketSetting:2;
   } option;
   uint8_t channel; // E220_REG_ADDR_CHNL
}

我能够将它的一部分转换成Python。(但可能没有正确的方法。)

class StHeader(NamedTuple):
    cmd: c_uint8
    start_addr: c_uint8
    length: c_uint8

class StCfg(NamedTuple):
    # class StHeader cmd_header
    # Q: How to include StHeader class here without allocation?

    ADDH: c_uint8
    ADDL: c_uint8
    # // E220_REG_SPEED
    class StSpeed(Structure):
        _fields_ = [
            ('airDataRate', c_uint8, 3),
            ('uartParity', c_uint8, 2),
            ('uartBaudRate', c_uint8, 3)
        ]

我尝试了不同的方法...

class StHeader(Structure):
    _fields_ = [
        ('cmd', c_uint8),
        ('start_addr', c_uint8),
        ('length', c_uint8)
    ]

class StSpeed(Structure):
    _fields_ = [
        ('air_data_rate', c_uint8, 3),
        ('uart_parity', c_uint8, 2),
        ('uart_baudrate', c_uint8, 3)
    ]

class StCfg(Structure):
    _fields_ = [
        ('cmd_header', StHeader),
        ('ADDH', c_uint8),
        ('ADDL', c_uint8),
        ('speed', StSpeed),
        ('option', StOption),
        ('channel', c_uint8),

它多-少工作,但是,是不是可以将它添加到嵌套类中,如

class M():
    class stA(Structure):
        _fields_ = [
            ('a', c_uint8)
        ]

    class stB(Structure):
        _fields_ = [
            ('stA', stA),
            ('b', c_uint8)
        ]

它找不到stA符号,而嵌套。
所以让我们关注问题的第二部分,如何将数据(字节)解释为结构?

data = b'\xc1\x00\x08\x00Zb\xc0\n\xd3\x00\x00'
st = StCfg()
# interprets data as s StCfg structure without copying

# did not work, missing method
st.from_buffer_copy(data)

# Q: This works fine, but does not have some side effects?
memmove(byref(st), data, sizeof(st))

我做了什么,没事吧?
//编辑:好的,一直都没问题,只是语法错误。但是如何在BigEndian中使用Union在Python 3.9中不可用?
谢谢

qyyhg6bp

qyyhg6bp1#

我做了以下工作:

from ctypes import Structure, c_uint8

class StOption(Structure):
    _fields_ = [
        ("transmisstingPower", c_uint8, 2),
        ("three", c_uint8, 3),
        ("RSSIAmbientNoise", c_uint8, 1),
        ("subPacketSetting", c_uint8, 2),
    ]

class StHeader(Structure):
    _fields_ = [
        ("cmd", c_uint8),
        ("start_addr", c_uint8),
        ("length", c_uint8),
    ]

class StSpeed(Structure):
    _fields_ = [
        ("air_data_rate", c_uint8, 3),
        ("uart_parity", c_uint8, 2),
        ("uart_baudrate", c_uint8, 3),
    ]

class StCfg(Structure):
    _fields_ = [
        ("cmd_header", StHeader),
        ("ADDH", c_uint8),
        ("ADDL", c_uint8),
        ("speed", StSpeed),
        ("option", StOption),
        ("channel", c_uint8),
    ]

if __name__ == "__main__":
    data = b"\xc1\x00\x08\x00Zb\xc0\n\xd3\x00\x00"
    st = StCfg.from_buffer_copy(data)
    print("data in:", bytes(st).hex(' '))
    print(f"cmd: {st.cmd_header.cmd}")
    print(f"air data rate: {st.speed.air_data_rate}")

并得到的输出为:

data in: c1 00 08 00 5a 62 c0 0a
cmd: 193
air data rate: 2

相关问题