【问题标题】:Python3 ctypes copy pointer to ctypes.structurePython3 ctypes 将指针复制到 ctypes.structure
【发布时间】:2021-10-06 05:58:58
【问题描述】:

linux 内核的 ioctl 将结构放入结构中。我正在尝试弄清楚如何对 ctypes 做同样的事情。

我从 ioctl 收到 ParentRq。我想要一种将 Message.data 中的数据复制到另一个结构中的通用方法,例如 EventID。

from ctypes import Structure, c_uint8, c_uint16, POINTER

class EventID(Structure):
    _pack_ = 1
    _fields_ = [
        ('recent_addition_timestamp', c_uint8 * 4),
        ('last_recid', c_uint8 * 2),
        ('last_sw_processed_id', c_uint8 * 2),
        ('last_processed_id', c_uint8 * 2),
    ]
    _eventid_sampledata = [0x88, 0x29, 0xfd, 0x60, 0x3c, 0x02, 0xff, 0xff, 0x3c, 0x02]

class Message(Structure):
    _pack_ = 1
    _fields_ = [
        ('data_len', c_uint16),
        ('data', POINTER(c_uint8))
]

class ParentRq(Structure):
    _pack_ = 1
    _fields_ = [
        ('msg', Message)
    ]

p = ParentRq()
p.msg.data_len = len(EventID._eventid_sampledata)
p.msg.data = (c_uint8 * p.msg.data_len)(*EventID._eventid_sampledata)

# Proof that items got copied into the pointer correctly.
items = []
for i in range(p.msg.data_len):
    items.append(hex(p.msg.data[i]))
# items -> ['0x88', '0x29', '0xfd', '0x60', '0x3c', '0x2', '0xff', '0xff', '0x3c', '0x2']

# Copy p.msg.data into EventID
# How do I copy p.msg.data into EventID?
eid = EventID()

【问题讨论】:

    标签: python-3.x ctypes ioctl


    【解决方案1】:

    上市[Python.Docs]: ctypes - A foreign function library for Python

    有很多方法可以实现,一种是使用 memmove

    >>> import ctypes as ct
    >>>
    >>>
    >>> class EventID(ct.Structure):
    ...     _pack_ = 1
    ...     _fields_ = [
    ...         ("recent_addition_timestamp", ct.c_uint8 * 4),
    ...         ("last_recid", ct.c_uint8 * 2),
    ...         ("last_sw_processed_id", ct.c_uint8 * 2),
    ...         ("last_processed_id", ct.c_uint8 * 2),
    ...     ]
    ...
    >>>
    >>> l = [0x88, 0x29, 0xfd, 0x60, 0x3c, 0x02, 0xff, 0xff, 0x3c, 0x02]
    >>> size = len(l)
    >>> arr = (ct.c_ubyte * size)(*l)
    >>> ptr = ct.cast(arr, ct.POINTER(ct.c_ubyte))  # The equivalent of Message.data (ParentRq.msg.data) instance
    [hex(ptr[i]) for i in range(size)]
    >>> ['0x88', '0x29', '0xfd', '0x60', '0x3c', '0x2', '0xff', '0xff', '0x3c', '0x2']
    >>>
    >>> eid = EventID()  # Initialize members to default values (0)
    >>>
    >>> for f, _ in EventID._fields_:
    ...     print(f, [hex(i) for i in getattr(eid, f)[:]])
    ...
    recent_addition_timestamp ['0x0', '0x0', '0x0', '0x0']
    last_recid ['0x0', '0x0']
    last_sw_processed_id ['0x0', '0x0']
    last_processed_id ['0x0', '0x0']
    >>>
    >>> ct.memmove(ct.addressof(eid), ptr, size)
    2361449631368
    >>>
    >>> for f, _ in EventID._fields_:
    ...     print(f, [hex(i) for i in getattr(eid, f)[:]])
    ...
    recent_addition_timestamp ['0x88', '0x29', '0xfd', '0x60']
    last_recid ['0x3c', '0x2']
    last_sw_processed_id ['0xff', '0xff']
    last_processed_id ['0x3c', '0x2']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 2013-01-08
      • 2015-01-17
      相关资源
      最近更新 更多