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__
似乎我无法用枚举 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__