I am trying to use the bit fields in a useful way to create packed fields that can be sent out as packets. Let's see if my code can help explain:

from ctypes import *

class myPacketHeader(Structure):
    _pack_ = 1
    _fields_ = [("seqnum", c_ubyte, 8),
                ("is_command", c_uint, 1),
                ("address", c_uint, 31),
                ("length", c_ubyte, 8)]
   
header = myPacketHeader()
header.seqnum = 255
header.is_command = 1
header.address = 0x1234
header.length = 54

print "Size of header is: %d" % sizeof(header)

# Now I would like to send out the packed bytes...

This looks to work as I would like -- the output is:

Size of header is: 6

The next step is to convert the header to an array of bytes (or a list). I'd hope that there is a built-in method to get the packed bytes. Anyone know how to get there?

/Damon

Recommended Answers

All 3 Replies

I am trying to use the bit fields in a useful way to create packed fields that can be sent out as packets. Let's see if my code can help explain:

from ctypes import *

class myPacketHeader(Structure):
    _pack_ = 1
    _fields_ = [("seqnum", c_ubyte, 8),
                ("is_command", c_uint, 1),
                ("address", c_uint, 31),
                ("length", c_ubyte, 8)]
   
header = myPacketHeader()
header.seqnum = 255
header.is_command = 1
header.address = 0x1234
header.length = 54

print "Size of header is: %d" % sizeof(header)

# Now I would like to send out the packed bytes...

This looks to work as I would like -- the output is:

Size of header is: 6

The next step is to convert the header to an array of bytes (or a list). I'd hope that there is a built-in method to get the packed bytes. Anyone know how to get there?

/Damon

Adding a bit more info here. What I'd like is to get from class myPacketHeader above to a list that looks something like this:

header = myPacketHeader()
header.seqnum = 255
header.is_command = 1
header.address = 0x1234
header.length = 54

li = []
li = ConvertHeaderToList(header)
print li
# Now li should look like this
# [ 0xff,  0x34, 0x12, 0x00, 0x80, 0x36 ]

Again, thanks for any help.

On my i386 PC you need to reverse the "address" and "is_command" values to shift the 1 to the far left.

It's easy enough to make up a union to output what you want. It should be easy to convert any structure to a byte array but I don't know how to do that. But try this:

from ctypes import *
class myPacketHeader(Structure):
    _pack_ = 1
    _fields_ = [("seqnum", c_ubyte, 8),
                ("address", c_uint, 31),
                ("is_command", c_uint, 1),
                ("length", c_ubyte, 8)]

class myUnion(Union):
    _pack_ = 1
    _fields_ = [("header", myPacketHeader),
                ("bytes", c_uint8 * 6)]

hdr = myPacketHeader()
hdr.seqnum = 255
hdr.is_command = 1
hdr.address = 0x1234
hdr.length = 54
print "Size of hdr is: %d" % sizeof(hdr)
hun = myUnion(hdr)
["0x%02x" % x for x in hun.bytes]

To produce ['0xff', '0x34', '0x12', '0x00', '0x80', '0x36']

I suspected that ctypes Union was part of the solution.

Exactly what I was looking for! Much Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.