Come imballare e spacchettare usando i tipi (Struttura < - > str)
Domanda
Questa potrebbe essere una domanda sciocca ma non sono riuscito a trovare una buona risposta nei documenti o in nessun altro posto.
Se uso struct per definire una struttura binaria, la struttura ha 2 metodi simmetrici per la serializzazione e la deserializzazione (comprimere e decomprimere) ma sembra che ctypes non abbia un modo semplice per farlo. Ecco la mia soluzione, che sembra sbagliata:
from ctypes import *
class Example(Structure):
_fields_ = [
("index", c_int),
("counter", c_int),
]
def Pack(ctype_instance):
buf = string_at(byref(ctype_instance), sizeof(ctype_instance))
return buf
def Unpack(ctype, buf):
cstring = create_string_buffer(buf)
ctype_instance = cast(pointer(cstring), POINTER(ctype)).contents
return ctype_instance
if __name__ == "__main__":
e = Example(12, 13)
buf = Pack(e)
e2 = Unpack(Example, buf)
assert(e.index == e2.index)
assert(e.counter == e2.counter)
# note: for some reason e == e2 is False...
Soluzione
Il wiki PythonInfo ha una soluzione per questo.
FAQ: Come copio i byte su Python da una ctypes.Structure?
def send(self): return buffer(self)[:]
FAQ: Come copio i byte in un tipo. Struttura da Python?
def receiveSome(self, bytes): fit = min(len(bytes), ctypes.sizeof(self)) ctypes.memmove(ctypes.addressof(self), bytes, fit)
Il loro send
è l'equivalente (più o meno) di pack
e receiveSome
è una specie di pack_into
. Se hai un "quot" sicuro " situazione in cui si sta spacchettando in una struttura dello stesso tipo dell'originale, è possibile una riga come memmove (addressof (y), buffer (x) [:], sizeof (y))
per copiare x
in y
. Ovviamente, avrai probabilmente una variabile come secondo argomento, piuttosto che un pacchetto letterale di x
.
Altri suggerimenti
Dai un'occhiata a questo link su I / O binari in python:
http://www.dabeaz.com /blog/2009/08/python-binary-io-handling.html
In base a questo puoi semplicemente scrivere quanto segue per leggere da un buffer (non solo file):
g = open("foo","rb")
q = Example()
g.readinto(q)
Scrivere è semplicemente:
g.write(q)
Lo stesso per l'utilizzo dei socket:
s.send(q)
e
s.recv_info(q)
Ho fatto alcuni test con pack / unpack e ctypes e questo approccio è il più veloce tranne che per scrivere direttamente in C
Testato su Python3
e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)