在Python ctypes中将类型转换为数组

3
我正在尝试将由socket.inet_pton返回的16字节数据块转换为无符号字节的ctypes数组。我的数据结构如下:
class in6_addr(ctypes.Structure):
    _fields_ = (("Byte", ctypes.c_ubyte * 16),)
而这个数据块只是:
data = socket.inet_pton(socket.AF_INET6, "2001::3")
然而,以下尝试会导致错误:
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))
所有代码:http://codepad.org/2cjyVXBA 有什么想法需要转换成什么类型吗?
3个回答

3
我可能完全错了(而且似乎有点复杂),但这对我有效:

我不确定,但是这个在IT技术方面对我来说可行:

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

我必须将数据转换为整数列表并对其进行解包以供构造函数使用。一定有更简单的方法!


1
可以更简单:sin6.Byte = (ctypes.c_ubyte * 16)(*data) - Mark Tolonen

2

有人认为更容易:

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

或者:

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

使用字节流:
import io
io.BytesIO(data).readinto(sin6.Byte)

由于所考虑的结构只包含一个字段,因此可以省略字段名称。
sin6 = (ctypes.c_ubyte * 16)(*data)

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

io.BytesIO(data).readinto(sin6)

0

最简单的方法:

import ctypes
import socket

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

data = socket.inet_pton(socket.AF_INET6, "2001::3")

sin6 = in6_addr()
sin6.Byte[:] = data   # copy the data into a complete slice of the array

一些辅助方法也使类的使用更加容易:
import ctypes
import socket

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

    def __init__(self, data):
        self.Byte[:] = data

    def __repr__(self):
        return f'in6_addr(Bytes=bytes({list(self.Byte)}))'

data = socket.inet_pton(socket.AF_INET6, "2001::3")
sin6 = in6_addr(data)
print(sin6)

输出:

in6_addr(Bytes=bytes([32, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3]))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接