使用 Python 的枚举模块来处理 ctypes

4
enum模块出现之前,c_int或相关类型经常被用作替代枚举。但这没有类型检查。

现在Python有了一个enum模块,是否有一种方法可以直接与ctypes一起使用呢?

1个回答

3

是的,我们可以通过ctypes轻松创建自己的CEnum类,这得益于ctypes允许我们使用自定义类的选项。枚举类型由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

以下是一个示例(虽然滥用类型,但正确展示了用法):

windll.kernel32.GetModuleHandleA.argtypes = [EnumA]

>>> windll.kernel32.GetModuleHandleA(EnumA.CONST)
>>> windll.kernel32.GetModuleHandleA(EnumB.CONST)
ArgumentError: argument 1: <class 'TypeError'>: 

顺便提一下,我已经转换到CFFI,它原生支持枚举类型,并且使用的是 C 定义,这比 ctype 更加简洁。


当我在Python 3.4.1上运行您的代码时,我没有收到任何“ValueError”--同时显示的错误消息似乎很奇怪,难道不应该是“ValueError:0不是有效的EnumA”吗? - martineau
@eryksun 嗯,不确定发生了什么问题,已经修复。 - simonzack
不幸的是,这不允许我在ctypes.Structure定义中将CEnum子类用作C类型。我已经为此提出了一个新的问题(http://stackoverflow.com/questions/36877391/using-an-intenum-as-the-type-in-a-ctypes-structure-fields)。 - Vlad Firoiu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接