提问人:Wör Du Schnaffzig 提问时间:12/24/2020 最后编辑:Wör Du Schnaffzig 更新时间:12/24/2020 访问量:373
Python3、ctypes API 和枚举
Python3, ctypes API and Enum
问:
似乎我无法实例化 ctypes。具有枚举返回值的 CFUNCTYPE 原型,即使枚举包含 classmethod 也是如此。
有人经历过吗?
也许有解决方法吗?
我做错了什么吗?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
答:
1赞
Ethan Furman
12/24/2020
#1
这里有几个问题:
的返回值返回到 C 例程,因此必须是标准 ctypes 类型(不是 ctype 类型)
pyfunc
E
既没有,也没有似乎被调用为返回类型
from_param
_as_parameter_
要解决这些问题,您必须
- 将 in 更改为
E
@ct.CFUNCTYPE
ct.c_int
以及以下其中一项:
- 使用代替
IntEnum
Enum
或
- 返回
E(a).value
或
- 将 and 添加到您的枚举中(这使得它足够像):
__int__
__index__
int
ctypes
class E(enum.Enum):
A = 10
#
def __int__(self):
return self.value
__index__ = __int__
评论
0赞
Wör Du Schnaffzig
12/24/2020
“pyfunc 的返回值将返回 [,,,]” -> 不,pyfunc 被调用方的返回值将返回到 python 调用方。“既不是from_param也不是as_parameter [...]” -> 请参阅我添加的示例,即 ctypes 确实可以在枚举成员中转换c_int返回值。
0赞
Mark Tolonen
12/24/2020
@pqans,但通常 -wrapped 函数由 C 调用者调用,并且它无法处理 Python Enum 对象。如果您使用 Python 调用程序调用它,请不要使用 .CFUNCTYPE
CFUNCTYPE
0赞
Wör Du Schnaffzig
12/24/2020
如果它的行为与原始 c 函数不同,则它不是单元测试的适当模拟。但现在我明白了为什么 CFUNCTYPE 会以这种方式行事。
下一个:更改分面标签文本和背景颜色
评论
IntEnum