CTypes 位域设置整个字节

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

我有以下结构:

class KeyboardModifiers(Structure):
    _fields_ = [
        ('left_control', c_bool, 1),
        ('right_control', c_bool, 1),
        ('left_shift', c_bool, 1),
        ('right_shift', c_bool, 1),
        ('left_alt', c_bool, 1),
        ('right_alt', c_bool, 1),
        ('left_meta', c_bool, 1),
        ('right_meta', c_bool, 1),
        ('left_super', c_bool, 1),
        ('right_super', c_bool, 1),
        ('left_hyper', c_bool, 1),
        ('right_hyper', c_bool, 1),
    ]

它表示由 C 函数返回的结构,字段已正确设置并返回其值,设置字段时会出现问题。例如,如果我要做类似的事情:

my_keyboard_mods.left_shift = True

前 8 个字段将被设置为 True,与接下来的 8 个字段类似。似乎发生的情况是,它设置了整个字节的值,而不考虑位字段。我的问题是:

  1. 我做错了什么,那么到底是哪里出了问题呢?
  2. 这是 ctypes 的一个错误,有解决方法吗?

谢谢。

python ctypes bit-fields
1个回答
0
投票

它是使用

c_bool
的结果。 我没有将整个字节设置为 1,但导致非零字节的位集结果为 1,而不是所描述的 0xFF。它可能是操作系统或实现细节。 仅供参考:请确保下次发布重现问题的完整代码。

from ctypes import *

class KeyboardModifiers(Structure):
    _fields_ = [
        ('left_control', c_bool, 1),
        ('right_control', c_bool, 1),
        ('left_shift', c_bool, 1),
        ('right_shift', c_bool, 1),
        ('left_alt', c_bool, 1),
        ('right_alt', c_bool, 1),
        ('left_meta', c_bool, 1),
        ('right_meta', c_bool, 1),
        ('left_super', c_bool, 1),
        ('right_super', c_bool, 1),
        ('left_hyper', c_bool, 1),
        ('right_hyper', c_bool, 1),
    ]

k = KeyboardModifiers()
k.left_control = True
k.left_shift = True
k.right_hyper = True
print(bytes(k))

预期

b'\x05\0x08'
但由于
c_bool
实现将非零字节视为 1,因此得到以下输出:

b'\x01\x01'

使用

c_ubyte
c_ushort
代替:

from ctypes import *

class KeyboardModifiers(Structure):
    _fields_ = [
        ('left_control', c_ubyte, 1),
        ('right_control', c_ubyte, 1),
        ('left_shift', c_ubyte, 1),
        ('right_shift', c_ubyte, 1),
        ('left_alt', c_ubyte, 1),
        ('right_alt', c_ubyte, 1),
        ('left_meta', c_ubyte, 1),
        ('right_meta', c_ubyte, 1),
        ('left_super', c_ubyte, 1),
        ('right_super', c_ubyte, 1),
        ('left_hyper', c_ubyte, 1),
        ('right_hyper', c_ubyte, 1),
    ]

k = KeyboardModifiers()
k.left_control = True
k.left_shift = True
k.right_hyper = True
print(bytes(k))

输出:

b'\x05\x08'
© www.soinside.com 2019 - 2024. All rights reserved.