Reputation: 3437
On an embedded device running a C application, I have defined this struct:
struct TestStruct
{
float first;
int second;
char third;
};
On request, I send this struct via sockets:
else if(strcmp(str, "Get Stru") == 0)
{
TestStruct testStruct;
testStruct.first = 1.2;
testStruct.second = 42;
testStruct.third = 'A';
INT32 sendDataLength = send(m_Socket, (char *)(&testStruct), sizeof(testStruct), 0);
}
and read it from a Python script on my desktop:
import struct
import socket
from ctypes import *
class YourStruct(Structure):
_fields_ = [('v', c_float),
('t', c_int),
('c', c_char)]
s = socket.socket()
host = '127.0.0.1'
port = 1234
s.connect((host, port))
s.send('Get Stru'.encode())
data = s.recv(20)
print(data)
x = YourStruct()
This is the data printed to console on my desktop:
How can i reassemble the data
into a YourStruct
?
Note that the embedded device uses little endian, so I have had to use struct.unpack("<" + "f" * 2048, data)
to reassemble an array of floats.
Upvotes: 3
Views: 6492
Reputation: 41167
[Python.Docs]: struct - Interpret bytes as packed binary data contains all the needed intel.
code00.py:
#!/usr/bin/env python
import ctypes as ct
import struct
import sys
class SampleStruct(ct.Structure):
_fields_ = (
("v", ct.c_float),
("t", ct.c_int),
("c", ct.c_char),
)
def main(*argv):
data = b"\x9a\x99\x99?*\x00\x00\x00A\xbe\xad\xde"
x = SampleStruct()
fmt = "<fic"
fmt_size = struct.calcsize(fmt)
x.v, x.t, x.c = struct.unpack(fmt, data[:fmt_size])
print("Fields\n v: {:f}\n t: {:d}\n c: {:s}".format(x.v, x.t, x.c.decode()))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Notes:
Starting from the point where the data (data) was received from the socket
The format passed to struct.unpack (fmt arg) tells it how the data is organized: in our case it's "<fic"
: float, int, char (preceded by the little endian marker)
Also calculating the size (in bytes) of data that the format requires: it's 9 (4 + 4 + 1). data has 12 bytes, so ignoring the last 3, otherwise struct.unpack will spit struct.error
Check [SO]: Python struct.pack() behavior for more details on struct.pack
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048822543]> "e:\Work\Dev\VEnvs\py_pc064_03.07.09_test0\Scripts\python.exe" ./code00.py Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] 064bit on win32 Fields v: 1.200000 t: 42 c: A Done.
Upvotes: 4