我在C中有一个枚举数据类型。我应该如何在python-ctypes中声明它?我想让这个枚举变量成为一个结构的一部分,并且这个结构的赋值将通过memmove完成。分配后,我想显示结构中每个变量的值,以及我想要显示枚举字符串的枚举类型。如何在python中定义C-Enumeration类型
回答
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
嗨感谢您的答案。但是,你能解释一下吗?到目前为止,分配这个变量的唯一方法是通过memmove。在我这样做后,我可以使用getattr()读取分配给结构中其他'c_uint'变量的值。我不确定在这个对象中调用什么方法来获取分配给ctypes-structure中该变量的值。 – 2015-02-09 16:52:54
非常感谢。这正是我想要的。再次感谢您花时间纠正这个问题:-) – 2015-02-09 18:55:47
没问题,用元类很好的锻炼 – 2015-02-09 18:57:02
的Antti哈帕拉做了一个幻想ic工作回答!但是,当我将Python 3.2.2用于我认为值得注意的事情时,我遇到了一些小问题。相反的:
class CEnumeration(c_uint):
__metaclass__ = EnumerationType
_members_ = {}
你需要做的:
class CEnumeration(c_uint, metaclass = EnumerationType):
_members_ = {}
而且,int和long一直在Python 3,以便统一:
def __eq__(self, other):
if isinstance(other, (int, long)):
return self.value == other
return type(self) == type(other) and self.value == other.value
变为:
def __eq__(self, other):
if isinstance(other, int):
return self.value == other
return type(self) == type(other) and self.value == other.value
- 1. 如何使用C API在Python中定义新类型(类)?
- 2. 如何在Python中定义一个类
- 3. 如何在Python中为类定义[]?
- 4. 如何在python中定义一个匿名类型
- 5. Python类型没有定义
- 6. 如何定义循环类型定义?
- 7. 如何做“类型定义”
- 8. 如何在json-schema中定义自定义对象类型
- 9. 如何在WSDL中定义自定义类型的数组?
- 10. 如何在xsd中定义自定义数据类型?
- 11. 如何在Rust中定义自定义的`Error`类型?
- 12. 键入python:在类定义中使用类自己的类型
- 13. 在Python中定义类
- 14. 如何定义一个类型的别名在Python类型提示
- 15. 如何在类型描述中指定类定义作为参数类型
- 16. 在F#中,如何实例化一个泛型类型定义?
- 17. 如何在Java泛型中使用自定义类型
- 18. 如何在TypeScript中定义变量的静态类类型?
- 19. 如何在现有类型中声明或定义泛型xsd类型。
- 20. 如何在Google自定义搜索中指定图片类型
- 21. 定义类泛型类型
- 22. python类型错误:a未定义
- 23. Python用户定义的数据类型
- 24. (Python类型提示)如何指定当前定义的类型作为方法的返回类型?
- 25. 定义类型
- 26. 类型定义
- 27. 如何在COM接口定义中指定用户定义的类型参数?
- 28. Python。如何采取自定义类型的对象从* ARGS
- 29. 如何定义基本类型的泛型类型限制?
- 30. 如何在python中的子进程中指定数据类型?
你指的是什么课程? – Makoto 2015-02-09 15:51:02
是的。 https://docs.python.org/2/library/ctypes.html我上次checket时,addressof不是C;) – deets 2015-02-09 15:51:02
“header”是Ctypes-Structure的一个实例。我想知道当我尝试通过memmove分配“标题” - 实例的变量时,将调用“标题”是哪个类的哪个方法。从术语memmove,我可以猜测它必须是内存拷贝,它甚至可能不知道这个拷贝在哪里完成。因此,不会调用Ctypes-Structure类的方法。那是对的吗? – 2015-02-09 15:59:37