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 Wiki 이를위한 해결책이 있습니다.
FAQ : ctypes.structure에서 바이트를 파이썬에 어떻게 복사합니까?
def send(self): return buffer(self)[:]
FAQ : 파이썬에서 구조를 ctypes에 바이트를 복사하려면 어떻게해야합니까?
def receiveSome(self, bytes): fit = min(len(bytes), ctypes.sizeof(self)) ctypes.memmove(ctypes.addressof(self), bytes, fit)
그들의 send
(또는 더 많은) 동등한 것입니다 pack
, 그리고 receiveSome
일종의 a 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로 약간의 테스트를 했으며이 접근법은 C에서 똑바로 쓰는 것을 제외하고 가장 빠릅니다.
Python3에서 테스트
e = Example(12, 13)
serialized = bytes(e)
deserialized = Example.from_buffer_copy(serialized)