0

I am writing a script in python and have worked only on C and C++ all my life. What i want is to take in some parameters from caller and then create a 32 byte packet. Packet contains some bytes, some DWORDS, some bit fields etc. So i want to create this packet and then copy it over byte-by-byte (this is important) into a buffer which is allocated by a low level driver.

In C/C++ this is straight forward. Define a struct, program the fields and then read it byte by byte and copy it over to the buffer.

How can i do this in python? Looks like i can't define a class/struct which contains my 32 byte packet and then iterate over its members to copy them down byte by byte.

Any suggestions?

  • [If you're looking for C-like structures in python](https://stackoverflow.com/questions/35988/c-like-structures-in-python) – Shahlin Ibrahim Feb 03 '19 at 13:13
  • 1
    Have a look at: https://docs.python.org/2/library/struct.html – e.dan Feb 03 '19 at 13:15
  • @ShahlinIbrahim I think i can write a simple class with members which define my 32 byte packet. But after that i want to iterate over that 32 byte packet, copying the packet over byte by byte. Is there a way to achieve this? – Ankit Duggal Feb 03 '19 at 14:00

1 Answers1

2

Python 3 has special type for binary strings called bytes, as opposed to unicode strings. This is in contrast to Python 2, where this was the default string type.

The simplest way to create one is struct.pack with its format strings. For example, if you have an unsigned short followed by a signed short in your struct and you want to encode them in network byte order (aka big endian):

import struct
data = struct.pack('>Hh', 0xAFFE, -5)

This creates the byte string b'\xaf\xfe\xff\xfb'. You can access the first byte with data[0] or iterate over them with for byte in data: or get len(data) etc.

You can write them into a (device) file in binary mode like this:

with open('/dev/myfile', 'wb') as f:
    f.write(data)

Or send them over an UDP socket:

from socket import socket, AF_INET, SOCK_DGRAM
sock = socket(AF_INET, SOCK_DGRAM)
sock.sendto(data, ('127.0.0.1', 9999))

The Python 3 struct module has more examples.

maxy
  • 4,971
  • 1
  • 23
  • 25
  • I think i haven't been able to clearly explain what my situation is. And apologise because i am coming from a C background. Let's take the following structure as an example. In my python script i want to form a struct of this format and then copy it byte by byte over to a buffer in memory. I am still not clear how this can be done in Python. `struct pktdef { uint8_t opCode; uint8_t subOpCode; uint16_t paramList; uint32_t addr; uint32_t size; uint8_t flag1; uint8_t flag2; uint16_t debugInfo; };` – Ankit Duggal Feb 03 '19 at 18:42
  • In Python you don't have raw memory access. You cannot control the memory layout of Python objects. There is no pointer arithmetic, except through libraries that create a wrapper around a raw buffer, like numpy. Have a look how [reference counting](https://docs.python.org/3/c-api/intro.html#objects-types-and-reference-counts) works in the API, this may clarify things for you. – maxy Feb 03 '19 at 19:21
  • Hmm. I think i should just use a bytearray of 32 bytes and program my parameters into it as requested by caller. Then iterate over this bytearray and copy 32 bytes into the destination buffer. What doesn't look good here is that i am programming a well defined packet in a bytearray and not a user defined object type which resembles that packet. But i think that is all i can do in this case. Thanks for your help anyways. – Ankit Duggal Feb 03 '19 at 19:49