如何在python中定义C-Enumeration类型

时间:2015-02-09 15:47:05

标签: python ctypes memmove

我在C中有一个枚举数据类型。我应该如何在python-ctypes中声明它?我希望这个枚举变量成为结构的一部分,并且通过memmove将值分配给此结构。在分配之后,我想显示结构中每个变量的值,以及我想要显示枚举字符串的枚举类型。

2 个答案:

答案 0 :(得分:7)

The Enumeration class suggested by Raj Kumar被打破,因为它需要运行__init__来设置变量中的新值,因此如果在C端更改了值,则无法使用class EnumerationType(type(c_uint)): def __new__(metacls, name, bases, dict): if not "_members_" in dict: _members_ = {} for key, value in dict.items(): if not key.startswith("_"): _members_[key] = value dict["_members_"] = _members_ else: _members_ = dict["_members_"] dict["_reverse_map_"] = { v: k for k, v in _members_.items() } cls = type(c_uint).__new__(metacls, name, bases, dict) for key,value in cls._members_.items(): globals()[key] = value return cls def __repr__(self): return "<Enumeration %s>" % self.__name__ class CEnumeration(c_uint): __metaclass__ = EnumerationType _members_ = {} def __repr__(self): value = self.value return "<%s.%s: %d>" % ( self.__class__.__name__, self._reverse_map_.get(value, '(unknown)'), value ) def __eq__(self, other): if isinstance(other, (int, long)): return self.value == other return type(self) == type(other) and self.value == other.value 。以下是其固定版本:

CEnumeration

现在可以申报class EBoolean(CEnumeration): FALSE = 0 TRUE = 1

class HeaderStruct(Structure):
    _fields_ = [("param1", EBoolean), 
                ("param2", c_uint)]

并使用它:

>>> header = HeaderStruct()
>>> header.param1
<EBoolean.FALSE: 0>
>>> memmove(addressof(header), b'\x01', 1)  # write LSB 0x01 in the boolean
>>> header.param1
<EBoolean.TRUE: 1>
>>> header.param1 == EBoolean.TRUE
True
>>> header.param1 == 1   # as a special case compare against ints
True
>>> header.param1.value
1L

示例:

{{1}}

答案 1 :(得分:0)

Antti Haapala做了出色的工作!但是,在使用Python 3.2.2时,我确实遇到了一些小问题,我认为值得注意。而不是:

require 'green_shoes'

Shoes.app do
    button "OK!"
    button "Are you sure?"
end

你需要这样做:

class CEnumeration(c_uint):
    __metaclass__ = EnumerationType
    _members_     = {}

此外,int和long已在Python 3中统一,所以:

class CEnumeration(c_uint, metaclass = EnumerationType):
    _members_     = {}

变为:

def __eq__(self, other):
        if isinstance(other, (int, long)):
            return self.value == other

        return type(self) == type(other) and self.value == other.value