开发者

casting to Arrays in Python ctypes

开发者 https://www.devze.com 2023-01-07 20:31 出处:网络
I\'m trying to convert a 16 byte blob of data returned by socket.inet_pton into a ctypes array of unsigned bytes. My data structure looks like this:

I'm trying to convert a 16 byte blob of data returned by socket.inet_pton into a ctypes array of unsigned bytes. My data structure looks like this:

class in6_addr(ctypes.Structure):
    _fields_ = (("Byte", ctypes.c_ubyte * 16),)

And the blob is just:

data = socket.inet_pton(socket.AF_INET开发者_运维问答6, "2001::3")

However, these attempts get errors:

sin6 = in6_addr()

# TypeError: expected c_ubyte_Array_16 instance, got str
sin6.Byte = data
# TypeError: cast() argument 2 must be a pointer type, not c_ubyte_Array_16
sin6.Byte = ctypes.cast(data, ctypes.c_ubyte * 16)
# TypeError: incompatible types, LP_c_ubyte instance instead of c_ubyte_Array_16 instance
sin6.Byte = ctypes.cast(data, ctypes.POINTER(ctypes.c_ubyte))

All of the code: http://codepad.org/2cjyVXBA

Any ideas what type I need to cast to?


I might be completely wrong here (and it does seem a bit complex) but this works for me:

sin6.Byte = (ctypes.c_ubyte*16)(*list(bytearray(data)))

I had to convert the data into a list of integers and unpack them for the constructor. There must be an easier way!


Arguably easier:

sin6.Byte = cast(data, ctypes.POINTER(ctypes.c_ubyte * 16)).contents

or:

sin6.Byte = (ctypes.c_ubyte * 16)(*[x for x in data])

Using bytes stream:

import io
io.BytesIO(data).readinto(sin6.Byte)

And since the considered structure contains the single field, the field name can be omited:

sin6 = cast(data, ctypes.POINTER(ctypes.c_ubyte * 16)).contents
sin6 = (ctypes.c_ubyte * 16)(*[x for x in data])
io.BytesIO(data).readinto(sin6)
0

精彩评论

暂无评论...
验证码 换一张
取 消