Before the enum
module existed, c_int
or related types were often used as substitute enums. But this did not have nor check for types.
Now that python has an enum
module, is there a way to use that directly with ctypes
?
Yes, we can easily create our own CEnum class thanks to ctypes allowing us the option to use custom classes. Enum types are checked automatically by ctypes.
from ctypes import windll
from enum import IntEnum
class CEnum(IntEnum):
@classmethod
def from_param(cls, self):
if not isinstance(self, cls):
raise TypeError
return self
class EnumA(CEnum):
CONST = 0
class EnumB(CEnum):
CONST = 0
Here's an example (which abuses types, but shows the usage correctly):
windll.kernel32.GetModuleHandleA.argtypes = [EnumA]
>>> windll.kernel32.GetModuleHandleA(EnumA.CONST)
>>> windll.kernel32.GetModuleHandleA(EnumB.CONST)
ArgumentError: argument 1: <class 'TypeError'>:
As an aside, I've since switched to cffi, which supports enums natively, and uses c definitions which happens to be a lot more concise compared to their ctype counterparts.