Question

C’est peut-être une question idiote mais je n’ai pas pu trouver de bonne réponse dans les documents ou ailleurs.

Si j'utilise struct pour définir une structure binaire, la structure dispose de 2 méthodes symétriques pour la sérialisation et la désérialisation (pack et unpack), mais il semble que ctypes ne fonctionne pas. un moyen simple de le faire. Voici ma solution, qui se sent 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...
Était-ce utile?

La solution

Le wiki PythonInfo a une solution pour cela.

  

FAQ: Comment copier des octets vers Python à partir d'un ctypes.Structure?

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

FAQ: Comment copier des octets dans un ctypes.Structure à partir de Python?

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

Leur send est l'équivalent (plus ou moins) de pack , et receiveSome est en quelque sorte un pack_into . Si vous avez un " coffre-fort " Lorsque vous décompressez dans une structure du même type que l'original, vous pouvez la mettre en ligne comme memmove (adressede (y), tampon (x) [:], sizeof (y)) pour copier x dans y . Bien sûr, vous aurez probablement une variable comme second argument, plutôt qu'un empilement littéral de x .

Autres conseils

Regardez ce lien sur les entrées / sorties binaires en python:

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

Sur cette base, vous pouvez simplement écrire ce qui suit pour le lire à partir d'un tampon (pas uniquement de fichiers):

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

Écrire c'est simplement:

g.write(q)

Idem pour l'utilisation de sockets:

s.send(q)

et

s.recv_info(q)

J'ai fait quelques tests avec pack / unpack et ctypes et cette approche est la plus rapide, sauf pour écrire directement en C

Testé sur Python3

e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top