Python3、ctypes API 和枚举

Python3, ctypes API and Enum

似乎我无法用枚举 return 值实例化 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")

<MyEnum.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

这里有几个问题:

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

  • from_param_as_parameter_ 似乎都不是 return 类型

要解决这些问题,您必须

  • @ct.CFUNCTYPE中的E改为ct.c_int

和以下之一:

  • 使用IntEnum代替Enum

  • return E(a).value

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