Przetwarzanie danych binarnych w ctypes Obiekt struktury poprzez readinto ()

Próbuję obsłużyć format binarny, podążając za przykładem tutaj:

http://dabeaz.blogspot.jp/2009/08/python-binary-io-handling.html

>>> from ctypes import *
>>> class Point(Structure):
>>>     _fields_ = [ ('x',c_double), ('y',c_double), ('z',c_double) ]
>>>
>>> g = open("foo","rb") # point structure data
>>> q = Point()
>>> g.readinto(q)
24
>>> q.x
2.0

Zdefiniowałem strukturę mojego nagłówka i próbuję odczytać dane do mojej struktury, ale mam pewne trudności. Moja struktura jest taka:

class BinaryHeader(BigEndianStructure):
    _fields_ = [
                ("sequence_number_4bytes", c_uint),
                ("ascii_text_32bytes", c_char),
                ("timestamp_4bytes", c_uint),
                ("more_funky_numbers_7bytes", c_uint, 56),
                ("some_flags_1byte", c_byte),
                ("other_flags_1byte", c_byte),
                ("payload_length_2bytes", c_ushort),

                ] 

Thedokumentacja ctypes mówi:

Dla pól typu całkowitego, takich jak c_int, można podać trzeci opcjonalny element. Musi to być mała dodatnia liczba całkowita określająca szerokość bitową pola.

Więc dla("more_funky_numbers_7bytes", c_uint, 56), Próbowałem zdefiniować pole jako pole 7-bajtowe, ale pojawia się błąd:

Błąd wartości: liczba niepoprawnych bitów dla pola bitowego

Moim pierwszym problemem jest to, jak mogę zdefiniować 7-bajtowe pole int?

Następnie, jeśli pominę ten problem i skomentuję pole „more_funky_numbers_7bytes”, wynikowe dane zostaną załadowane .. ale zgodnie z oczekiwaniami tylko 1 znak zostanie załadowany do „ascii_text_32bytes”. I z jakiegoś powodu powraca16 zakładam, że jest to obliczona liczba bajtów, które odczytuje do struktury ... ale jeśli komentuję moje pole "funky number" i "" ascii_text_32bytes "daje tylko jeden znak (1 bajt), czy nie powinno to być 13, nie 16 ???

Następnie próbowałem rozdzielić pole znakowe na oddzielną strukturę i odwołać się do tego w mojej strukturze nagłówka. Ale to też nie działa ...

class StupidStaticCharField(BigEndianStructure):
    _fields_ = [
                ("ascii_text_1", c_byte),
                ("ascii_text_2", c_byte),
                ("ascii_text_3", c_byte),
                ("ascii_text_4", c_byte),
                ("ascii_text_5", c_byte),
                ("ascii_text_6", c_byte),
                ("ascii_text_7", c_byte),
                ("ascii_text_8", c_byte),
                ("ascii_text_9", c_byte),
                ("ascii_text_10", c_byte),
                ("ascii_text_11", c_byte),
                .
                .
                .
                ]

class BinaryHeader(BigEndianStructure):
    _fields_ = [
                ("sequence_number_4bytes", c_uint),
                ("ascii_text_32bytes", StupidStaticCharField),
                ("timestamp_4bytes", c_uint),
                #("more_funky_numbers_7bytes", c_uint, 56),
                ("some_flags_1byte", c_ushort),
                ("other_flags_1byte", c_ushort),
                ("payload_length_2bytes", c_ushort),

                ] 

Wszelkie pomysły, jak:

Zdefiniuj pole 7-bajtowe (które będę musiał dekodować przy użyciu zdefiniowanej funkcji)Zdefiniuj statyczne pole char o 32 bajtach

AKTUALIZACJA

Znalazłem strukturę, która wydaje się działać ...

class BinaryHeader(BigEndianStructure):
    _fields_ = [
                ("sequence_number_4bytes", c_uint),
                ("ascii_text_32bytes", c_char * 32),
                ("timestamp_4bytes", c_uint),
                ("more_funky_numbers_7bytes", c_byte * 7),
                ("some_flags_1byte", c_byte),
                ("other_flags_1byte", c_byte),
                ("payload_length_2bytes", c_ushort),

                ]  

Teraz jednak pozostało mi pytanie, dlaczego podczas używania.readinto():

f = open(binaryfile, "rb")

mystruct = BinaryHeader()
f.readinto(mystruct)

Wraca52 a nie oczekiwane,51. Skąd pochodzi ten dodatkowy bajt i dokąd on idzie?

AKTUALIZACJA 2 Dla zainteresowanych jest toprzykład alternatywystruct metoda odczytu wartości w nazwanej kodzie wymienionym przez eryksun:

>>> record = 'raymond   \x32\x12\x08\x01\x08'
>>> name, serialnum, school, gradelevel = unpack('<10sHHb', record)

>>> from collections import namedtuple
>>> Student = namedtuple('Student', 'name serialnum school gradelevel')
>>> Student._make(unpack('<10sHHb', record))
Student(name='raymond   ', serialnum=4658, school=264, gradelevel=8)

questionAnswers(1)

yourAnswerToTheQuestion