Python ctypes如何正确初始化Structure结构体内的数组成员?
现象原因
你看到test_arr打印内存地址不是初始化失败,是ctypes的固定长度数组类型默认的字符串表示规则就是输出对象类型和内存地址,不会自动展开内部元素。
你当前写的ST_DATA(1, 2, (3, 4))初始化逻辑本身是合法的:传入的元组(3,4)已经被正确写入test_arr对应的内存空间,只是直接打印数组对象看不到具体元素值。
c_int、c_double这类基础标量类型的ctypes封装做了和Python原生数值类型的自动转换,打印时会直接显示数值;数组属于复合类型,没有实现自动转列表的默认打印逻辑,才会出现和基础字段输出不一致的情况。
数组字段的正确初始化、访问方式
ctypes结构体的数组成员初始化没有特殊语法,以下几种写法都是合法的:
- 初始化结构体时直接传入长度匹配的可迭代对象(元组、列表都可以),这也是最简洁的写法,和你当前的写法一致,只是访问元素需要按下标取值,或者手动转成Python列表查看内容:
from ctypes import * class ST_DATA(Structure): _fields_ = [("test1", c_int), ("test2", c_double), ("test_arr", c_double*2)] stmyData = ST_DATA(1, 2, (3, 4)) # 按下标访问单个元素 print(stmyData.test1, stmyData.test2, stmyData.test_arr[0], stmyData.test_arr[1]) # 转成Python原生列表打印全量内容 print(list(stmyData.test_arr))
运行后输出为:
1 2.0 3.0 4.0 [3.0, 4.0]
- 先显式构造ctypes数组实例,再传入结构体初始化参数,适合需要提前操作数组内容的场景:
# 先实例化长度为2的c_double数组 test_arr = (c_double * 2)(3, 4) stmyData = ST_DATA(1, 2, test_arr)
- 初始化空结构体之后,再给数组字段赋值,既可以直接传等长可迭代对象整体赋值,也可以逐个下标修改元素:
stmyData = ST_DATA() stmyData.test1 = 1 stmyData.test2 = 2 # 整体赋值 stmyData.test_arr = [3, 4] # 单个元素修改 stmyData.test_arr[0] = 5
注意:ctypes数组是固定长度,传入的初始化元素数量不能超过
_fields_里定义的数组长度,否则会抛出参数类型错误。
内容的提问来源于stack exchange,提问作者bombombee
相关产品推荐
相关产品推荐

