如何为Python3中ctypes定义的零长度数组赋值

问题描述 投票:0回答:1

这里我有一个如下定义的类,其属性data是一个[[zero-length数组。如何实例化此类?

class Frame(ctypes.Structure): _fields_ = [ ("id", ctypes.c_uint64), ("size", ctypes.c_uint32), ("data", ctypes.c_byte*0) # zero-length array ]
我尝试过此

frame = Frame() frame.id = 0 frame.size = 2 frame.data = ctypes.cast(b'12', ctypes.POINTER(ctypes.c_type * 0))

但是第4行出现了例外

TypeError: incompatible types, LP_c_byte_Array_0 instance instead of c_byte_Array_0 instance

所以,我应该如何正确地实例化该类?
python arrays ctypes zero
1个回答
0
投票
列出[Python 3.Docs]: ctypes - A foreign function library for Python

此技术(具有长度为

0长数组的struct作为最后一个成员)通常在C中使用,以便在struct之后具有可变数据。不幸的是,Python层不允许这样做(将大于其长度的值分配给数组)。与您的目标最接近的事情是将data成员声明为指针。更进一步,创建一个执行所有转换的setter方法:

code00.py

#!/usr/bin/env python3 import sys import ctypes as ct class Frame(ct.Structure): _fields_ = [ ("id", ct.c_uint64), ("size", ct.c_uint32), ("data", ct.POINTER(ct.c_ubyte)), # Make it a pointer ] def set_data(self, value): if not isinstance(value, (bytes,)): raise ValueError("Bytes expected.") self.data = ct.cast(value, ct.POINTER(ct.c_ubyte)) self.size = len(value) def main(): frame = Frame() frame.set_data(b"123abCD") for i in range(frame.size): print("{0:d} - {1:d}".format(i, frame.data[i])) if __name__ == "__main__": print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) main() print("\nDone.")

输出:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q059172596]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code00.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 0 - 49 1 - 50 2 - 51 3 - 97 4 - 98 5 - 67 6 - 68 Done.
© www.soinside.com 2019 - 2024. All rights reserved.