Python 中的动态 defining/updating ctypes 结构
Dynamically defining/updating ctypes structure in Python
我在 ctypes 中创建了子结构和结构,如下所示,我在结构内部定义了一个具有预定义大小的子结构数组。 (根据要求,SIZE
最初可能设置为 0
,并且会根据用户输入而变化)。
from ctypes import *
class MySubStructure(Structure):
_fields_ = [
("sub_field1", c_uint32),
("sub_field2", c_uint32)
]
class MyStructure(Structure):
SIZE = 2
_fields_ = [
("field1", c_uint32),
("field2", c_uint32),
("sub_structure_field", ARRAY(SubStructure, SIZE)),
]
我的目标是根据用户输入修改此子结构。
为了达到同样的效果,我尝试了以下选项但没有成功:
定义 __init__
方法并在初始化实例时更新 _fields_
初始化实例后更新_fields_
对于这两个选项,我都尝试附加 sub_structure_field
,通过索引访问仅更新大小值。
最后我只想要一个解决方法,这样我就可以在另一个结构中使用结构数组,要么在运行时初始化,要么在运行时修改。
提到[Python 3.Docs]: ctypes - A foreign function library for Python。
数组大小必须在定义 _fields_ 时已知。
你可以有一个定义 class 和 returns 的工厂函数。
script0.py:
#!/usr/bin/env python3
import sys
import ctypes
class SubStructure(ctypes.Structure):
_fields_ = [
("sub_field1", ctypes.c_uint32),
("sub_field2", ctypes.c_uint32),
]
def structure_factory(size):
class DynamicStructure(ctypes.Structure):
_fields_ = [
("field1", ctypes.c_uint32),
("field2", ctypes.c_uint32),
("sub_structure_field", ctypes.ARRAY(SubStructure, size)), # 2nd element equivalent to SubStructure * size
]
return DynamicStructure
def main():
Struct2 = structure_factory(2)
Struct5 = structure_factory(5)
print(Struct2.sub_structure_field)
print(Struct5.sub_structure_field)
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\Whosebug\q057417435]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" script0.py
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32
<Field type=SubStructure_Array_2, ofs=8, size=16>
<Field type=SubStructure_Array_5, ofs=8, size=40>
Done.
你也可以看看。
我在 ctypes 中创建了子结构和结构,如下所示,我在结构内部定义了一个具有预定义大小的子结构数组。 (根据要求,SIZE
最初可能设置为 0
,并且会根据用户输入而变化)。
from ctypes import *
class MySubStructure(Structure):
_fields_ = [
("sub_field1", c_uint32),
("sub_field2", c_uint32)
]
class MyStructure(Structure):
SIZE = 2
_fields_ = [
("field1", c_uint32),
("field2", c_uint32),
("sub_structure_field", ARRAY(SubStructure, SIZE)),
]
我的目标是根据用户输入修改此子结构。
为了达到同样的效果,我尝试了以下选项但没有成功:
定义
__init__
方法并在初始化实例时更新_fields_
初始化实例后更新
_fields_
对于这两个选项,我都尝试附加 sub_structure_field
,通过索引访问仅更新大小值。
最后我只想要一个解决方法,这样我就可以在另一个结构中使用结构数组,要么在运行时初始化,要么在运行时修改。
提到[Python 3.Docs]: ctypes - A foreign function library for Python。
数组大小必须在定义 _fields_ 时已知。
你可以有一个定义 class 和 returns 的工厂函数。
script0.py:
#!/usr/bin/env python3
import sys
import ctypes
class SubStructure(ctypes.Structure):
_fields_ = [
("sub_field1", ctypes.c_uint32),
("sub_field2", ctypes.c_uint32),
]
def structure_factory(size):
class DynamicStructure(ctypes.Structure):
_fields_ = [
("field1", ctypes.c_uint32),
("field2", ctypes.c_uint32),
("sub_structure_field", ctypes.ARRAY(SubStructure, size)), # 2nd element equivalent to SubStructure * size
]
return DynamicStructure
def main():
Struct2 = structure_factory(2)
Struct5 = structure_factory(5)
print(Struct2.sub_structure_field)
print(Struct5.sub_structure_field)
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\Whosebug\q057417435]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" script0.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 <Field type=SubStructure_Array_2, ofs=8, size=16> <Field type=SubStructure_Array_5, ofs=8, size=40> Done.
你也可以看看