Python Ctypes转换CM_POWER_DATA 解决DEVICE_POWER_STATE报错
问题根因
你遇到的报错和结构体定义错误来自三点:
- 未提前定义
DEVICE_POWER_STATE、SYSTEM_POWER_STATE两个类型,这两个是WDM定义的枚举类型,C语言中枚举默认占4字节内存,对应ctypes的32位整型类型。 - 你写的
_fields_序列存在语法错误:PD_D1Latency、PD_D3Latency字段行末尾缺失逗号,会导致Python错误合并相邻元组,字段解析失败。 - 数组成员定义方式错误:ctypes中数组类型需要用
基础类型 * 长度的语法声明,不能把数组长度写在字段名的字符串里;另外最后一个成员PD_DeepestSystemWake原生类型是SYSTEM_POWER_STATE,你误写为DEVICE_POWER_STATE。
正确实现代码
import ctypes as ct from ctypes import wintypes as w from enum import IntEnum # 映射WDM中DEVICE_POWER_STATE枚举 class DEVICE_POWER_STATE(IntEnum): PowerDeviceUnspecified = 0 PowerDeviceD0 = 1 PowerDeviceD1 = 2 PowerDeviceD2 = 3 PowerDeviceD3 = 4 PowerDeviceMaximum = 5 # 映射WDM中SYSTEM_POWER_STATE枚举 class SYSTEM_POWER_STATE(IntEnum): PowerSystemUnspecified = 0 PowerSystemWorking = 1 PowerSystemSleeping1 = 2 PowerSystemSleeping2 = 3 PowerSystemSleeping3 = 4 PowerSystemHibernate = 5 PowerSystemShutdown = 6 PowerSystemMaximum = 7 POWER_SYSTEM_MAXIMUM = SYSTEM_POWER_STATE.PowerSystemMaximum class CM_POWER_DATA(ct.Structure): _fields_ = [ ("PD_Size", w.ULONG), ("PD_MostRecentPowerState", ct.c_long), ("PD_Capabilities", w.ULONG), ("PD_D1Latency", w.ULONG), ("PD_D2Latency", w.ULONG), ("PD_D3Latency", w.ULONG), ("PD_PowerStateMapping", DEVICE_POWER_STATE * POWER_SYSTEM_MAXIMUM), ("PD_DeepestSystemWake", ct.c_long) ]
说明
- 如果你不需要读取枚举名做调试,可以直接把两个电源状态字段的类型替换为
ct.c_ulong或者w.ULONG,内存布局完全匹配,不会出现对齐错误。 - 用继承
IntEnum的类作为字段类型时,读取结构体成员会直接返回对应枚举值,不需要手动做数值到状态名的映射。 - 定义完结构体后可以用
ct.sizeof(CM_POWER_DATA)验证大小,32位和64位Windows下该结构体大小均为56字节,和原生C结构体大小一致就说明对齐和字段定义正确。
内容的提问来源于stack exchange,提问作者user19212551
相关产品推荐
相关产品推荐

