Pregunta

Esta podría ser una pregunta tonta, pero no pude encontrar una buena respuesta en los documentos ni en ningún otro lugar.

Si uso struct para definir una estructura binaria, la estructura tiene 2 métodos simétricos para la serialización y deserialización (empacar y desempaquetar) pero parece que ctypes no tiene Una forma sencilla de hacer esto. Aquí está mi solución, que se siente mal:

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...
¿Fue útil?

Solución

El wiki de PythonInfo tiene una solución para esto.

  

Preguntas frecuentes: ¿Cómo copio bytes a Python desde ctypes.Structure?

def send(self):
    return buffer(self)[:]
     

Preguntas frecuentes: ¿Cómo copio bytes a una estructura ctypes.Structure desde Python?

def receiveSome(self, bytes):
    fit = min(len(bytes), ctypes.sizeof(self))
    ctypes.memmove(ctypes.addressof(self), bytes, fit)

Su send es el equivalente (más o menos) de pack , y ReceiveSome es una especie de pack_into . Si tiene una "caja fuerte" situación en la que está desempacando en una estructura del mismo tipo que la original, puede alinearla en una línea como memmove (addressof (y), buffer (x) [:], sizeof (y)) para copiar x en y . Por supuesto, probablemente tendrá una variable como segundo argumento, en lugar de un paquete literal de x .

Otros consejos

Eche un vistazo a este enlace en E / S binaria en python:

http://www.dabeaz.com /blog/2009/08/python-binary-io-handling.html

Basado en esto, simplemente puede escribir lo siguiente para leer desde un búfer (no solo archivos):

g = open("foo","rb")
q = Example()
g.readinto(q)

Escribir es simplemente:

g.write(q)

Lo mismo para usar sockets:

s.send(q)

y

s.recv_info(q)

Hice algunas pruebas con pack / unpack y ctypes y este enfoque es el más rápido, excepto para escribir directamente en C

Probado en Python3

e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top