首页 > 解决方案 > Python3、ctypes API 和枚举

问题描述

即使 Enum 包含 classmethod ,我似乎也无法实例化具有 Enum 返回值的 ctypes.CFUNCTYPE 原型from_param。有人经历过吗?有没有解决方法,也许?我做错什么了吗?

这有效:

import ctypes as ct

@ct.CFUNCTYPE(ct.c_int, ct.c_int)
def pyfunc(a):
    return 100

print(pyfunc(10))

100

这也有效(linux):

import ctypes as ct
import enum


class MyEnum(enum.Enum):
    A = 1
    B = 2

    @classmethod
    def from_param(cls, param):
        return ct.c_int(param)


printf = ct.CDLL("libc.so.6").printf
printf.restype = MyEnum  
printf(b"1")

<我的枚举.A: 1>

printf(b"12")

<MyEnum.B: 2>

这失败了:

import ctypes as ct
import enum

class E(enum.Enum):
    A = 10
   
    @classmethod
    def from_param(cls, param):
        return ct.c_int(param)

 @ct.CFUNCTYPE(E, ct.c_int)
 def pyfunc(a):
     return E(10)
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    @ct.CFUNCTYPE(E, ct.c_int)
TypeError: invalid result type for callback function

标签: python-3.xenumscallbackprototypectypes

解决方案


这里有几个问题:

  • 的返回值pyfunc返回到 C 例程,因此必须是标准 ctypes 类型(E不是 ctype 类型)

  • 既不from_param也不_as_parameter_似乎被要求返回类型

要解决这些问题,您必须

  • 更改为E_@ct.CFUNCTYPEct.c_int

和以下之一:

  • 使用IntEnum而不是Enum

或者

  • 返回E(a).value

或者

  • __int__and添加__index__到您的枚举中(这使得它int足够像ctypes):
    class E(enum.Enum):
        A = 10
        #
        def __int__(self):
            return self.value
        __index__ = __int__

推荐阅读