How to determine types of C enums in python

I have an enumeration data type in C. How to declare this in python-ctypes? I want the enum variable to be part of the structure, and assigning values ​​to this structure is done through memmove. After the assignment, I want to display the values ​​of each variable in the structure, and for enumeration types I want to display the enumeration string.

+4
source share
2 answers

The Enumeration class proposed by Raj Kumar was violated by the fact that a new value in a variable was required to run __init__, and therefore unsuitable for use if the value was changed on the C side. Here is their fixed version:

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
+7

! , , 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
0

All Articles