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...
È stato utile?

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top