2
//c struct code with filed width:

    struct{
      unsigned int x:1;
      unsigned int y:25;
      unsigned int z:6;
    };

Now I want to rewrite it in python, pack it and send to network,

The package struct in python, can pack/unpack data types.

such as:

struct.pack('!I10s',1,'hello')

But I don't know how to deal with struct with filed width as the c struct example. Any one know?

jim ying
  • 361
  • 4
  • 17
  • any help http://stackoverflow.com/questions/7198388/accessing-bitfields-while-reading-writing-binary-data-structures ?? possibly a dupe. – Paul Rooney Dec 21 '16 at 06:12
  • 1
    3q. I have seen it. Now find a link maybe better, http://varx.org/wordpress/2016/02/03/bit-fields-in-python/ – jim ying Dec 21 '16 at 06:37
  • Just read the whole thing as an unsigned, then mask and shift. Like the linked article does. The portability of bit fields is questionable though. – Paul Rooney Dec 21 '16 at 11:24

1 Answers1

3

I realize it's late, but the following could help newcomers.

You can combine ctypes with struct.pack_into/struct.unpack_from:

import struct
import ctypes


class CStruct(ctypes.BigEndianStructure):
    _fields_ = [
        ("x", ctypes.c_uint32, 1),  # 1 bit wide
        ("y", ctypes.c_uint32, 25), # 25 bits wide
        ("z", ctypes.c_uint32, 6)   # 6 bits wide
    ]


cs = CStruct()

# then you can pack to it:
struct.pack_into('!I', cs,
                 0, # offset
                 0x80000083)
print(f'x={cs.x} y={cs.y} z={cs.z}')
# x=1 y=2 z=3

# or unpack from it:
cs_value, = struct.unpack_from('!I', cs)
print(hex(cs_value))
# 0x80000083
Shlomo Gottlieb
  • 519
  • 5
  • 11