Frage

Dies könnte eine dumme Frage, aber ich konnte nicht eine gute Antwort in der Dokumentation oder überall.

Wenn ich verwenden struct eine binäre Struktur zu definieren, die Struktur verfügt über 2 symmetrische Verfahren zur Serialisierung und Deserialisierung (Pack und entpacken) aber es scheint, ctypes nicht über eine einfache Möglichkeit, dies zu tun. Hier ist meine Lösung, die falsch anfühlt:

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...
War es hilfreich?

Lösung

The PythonInfo Wiki hat eine Lösung für dieses.

  

FAQ: Wie kann ich Bytes Python aus einem ctypes.Structure kopieren

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

FAQ: Wie kann ich kopieren Bytes in einem ctypes.Structure von Python

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

Ihre send ist die (mehr oder weniger) Äquivalent pack und receiveSome ist eine Art von pack_into. Wenn Sie eine „sichere“ Situation, wo Sie in einer Struktur des gleichen Typs wie das Original sind Auspacken, können Sie einzeilige es wie memmove(addressof(y), buffer(x)[:], sizeof(y)) x in y zu kopieren. Natürlich werden Sie wahrscheinlich eine Variable als das zweite Argument, anstatt eine wörtliche Verpackung von x.

Andere Tipps

Haben Sie einen Blick auf diesen Link auf binäre I / O in Python:

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

Auf dieser Basis können Sie einfach schreiben die folgenden von einem Puffer zu lesen (und nicht nur Dateien):

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

zu schreiben ist einfach:

g.write(q)

Das gleiche gilt für über Sockets:

s.send(q)

und

s.recv_info(q)

Ich habe einige Tests mit pack / entpacken und ctypes und dieser Ansatz ist die am schnellsten mit Ausnahme gerade in C schreiben

Getestet auf Python3

e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top