这可能是一个愚蠢的问题,但我无法在文档或任何地方找到一个好的答案。
如果我使用 struct 来定义二进制结构,那么struct有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...
答案 0 :(得分:28)
The PythonInfo wiki有解决方案。
FAQ:如何从ctypes.Structure复制字节到Python?
def send(self): return buffer(self)[:]
FAQ:如何从Python复制字节到ctypes.Structure?
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
的字面包装。
答案 1 :(得分:17)
在python中查看二进制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)
我使用pack / unpack和ctypes进行了一些测试,这种方法是最快的,除了直接用C语言写
答案 2 :(得分:4)
在Python3上测试
e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)