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