I have some binary data that I want to read via Python. I have the C code to do this, but I want to try it in Python.
Let's say the header of the file is as follows:
typedef struct
{
uint64_t message_time;
float lon, lat, alt;
int32_t extraint32[16];
float extrafloat[16];
char aircraft_name[100];
} AIRCRAFT_HEADER;
Using Python, I do the following:
from ctypes import *
class aircraft_header(Structure):
_fields_ = [('message_time', c_uint64),
('lon', c_float), ('lat', c_float), ('alt', c_float),
('extraint32[16]', c_int32),
('extrafloat[16]', c_float),
('aircraft_name[100]', c_char)
]
with open("../data/somefile.bin",mode='rb') as file:
result = []
allc = aircraft_header()
while file.readinto(allc) == sizeof(allc):
result.append((allc.message_time,
allc.lon, allc.lat, allc.alt,
allc.extraint32,
allc.extrafloat,
allc.aircraft_name))
This will throw the exception:
AttributeError: 'aircraft_header' object has no attribute 'extraint32'
How do I resolve this? Also, is there a more Pythonic way of reading this binary file?
CodePudding user response:
Take a look at the attributes available on an aicraft_header
object:
>>> example = aircraft_header()
>>> [x for x in dir(example) if not x.startswith('_')]
['aircraft_name[100]', 'alt', 'extrafloat[16]', 'extraint32[16]', 'lat', 'lon', 'message_time']
You have an attribute that is named literally extraint32[16]
,
which suggests you have an error in how your definining your
Structure
.
Taking a look at ctypes documentation, I think you want:
from ctypes import *
class aircraft_header(Structure):
_fields_ = [('message_time', c_uint64),
('lon', c_float), ('lat', c_float), ('alt', c_float),
('extraint32', c_int32 * 16),
('extrafloat', c_float * 16),
('aircraft_name', c_char * 100)
]
This appears to behave as expected:
>>> example.extraint32
<__main__.c_int_Array_16 object at 0x7fda7c9068c0>
>>> example.extraint32[0]
0
>>> example.extraint32[15]
0
>>> example.extraint32[16]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: invalid index