كيفية حزمة وفك باستخدام ctypes (هيكل <-> str)
سؤال
قد يكون هذا سؤال سخيف لكن لم أجد إجابة جيدة في المستندات أو في أي مكان.
إذا كنت تستخدم البنية لتحديد ثنائي الهيكل ، فإن البنية 2 متناظرة أساليب التسلسل وإلغاء التسلسل (حزمة وفك) ولكن يبدو ctypes لا يملك وسيلة واضحة للقيام بذلك.هنا هو الحل الذي يشعر الخطأ:
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...
المحلول
على PythonInfo ويكي وقد حل هذا.
التعليمات:كيف يمكنني نسخ بايت إلى الثعبان من ctypes.هيكل ؟
def send(self): return buffer(self)[:]
التعليمات:كيف يمكنني نسخ بايت إلى ctypes.هيكل من الثعبان ؟
def receiveSome(self, bytes): fit = min(len(bytes), ctypes.sizeof(self)) ctypes.memmove(ctypes.addressof(self), bytes, fit)
بهم send
هو (أكثر أو أقل) أي ما يعادل pack
, ، receiveSome
هو نوع من pack_into
.إذا كان لديك "آمنة" حالة حيث كنت الفتح في البنية من نفس النوع الأصلي ، يمكنك سطر واحد مثل memmove(addressof(y), buffer(x)[:], sizeof(y))
نسخ x
في y
.بالطبع سيكون لديك ربما متغير ما الحجة الثانية بدلا من حرفية التعبئة x
.
نصائح أخرى
إلقاء نظرة على هذا الرابط على الثنائية i/o في بايثون:
http://www.dabeaz.com/blog/2009/08/python-binary-io-handling.html
وبناء على هذا يمكن ببساطة كتابة التالية قراءة من المخزن المؤقت (وليس فقط الملفات):
g = open("foo","rb")
q = Example()
g.readinto(q)
أن تكتب هو ببساطة:
g.write(q)
نفس الشيء بالنسبة باستخدام مآخذ:
s.send(q)
و
s.recv_info(q)
فعلت بعض التجارب مع حزمة/فك ctypes و هذا النهج هو أسرع ما عدا الكتابة مباشرة في ج
اختبار على Python3
e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)