我想知道是否可以对各种类型的ctypes进行子类化。我尝试写了一个简单的例子,但有一件(或两件)事情我不明白。
为什么我的
PS:顺便问一句,为什么
编辑: 考虑另一个来自文档的例子:
from ctypes import *
class my_c_int(c_int):
pass
# def __new__(*args):
# print "Hello from __new__" # why is this not called?
libc = cdll.LoadLibrary("libc.dylib")
printf = libc.printf
# printf.restype = c_int # prints "14"
printf.restype = my_c_int # prints "<my_c_int object at 0x...>"
print printf("Hello, %s\n", "World!")
为什么我的
my_c_int
不返回与原始c_int
相同的类型,即int
?是否有可能这样做?如果我写print printf(...).value
就可以了。是否有可能自动为my_c_int
返回.value
?PS:顺便问一句,为什么
__new__
方法没有被调用?
编辑: 考虑另一个来自文档的例子:
from ctypes import *
libc = cdll.LoadLibrary("libc.dylib")
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
qsort = libc.qsort
qsort.restype = None
CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
def py_cmp_func(a, b):
print "py_cmp_func", a[0], b[0]
return a[0] - b[0]
cmp_func = CMPFUNC(py_cmp_func)
qsort(ia, len(ia), sizeof(c_int), cmp_func)
好的,这个没问题。我的问题是:是否可以修改CMPFUNC
函数接收的参数?是否可以通过使用一些自定义/子类化的ctypes类型来实现?
例如,假设我想直接传递整数(而不是指针)给py_cmp_func
。 我可以这样做:
from ctypes import *
libc = cdll.LoadLibrary("libc.dylib")
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
qsort = libc.qsort
qsort.restype = None
CMPFUNC = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
def auxiliary(a, b):
return py_cmp_func(a[0], b[0])
def py_cmp_func(a, b):
print "py_cmp_func", a, b
return a - b
cmp_func = CMPFUNC(auxiliary)
qsort(ia, len(ia), sizeof(c_int), cmp_func)
这也可以工作,但这不是我想要的。是否有可能在没有辅助
函数的情况下实现这种行为?就像:
from ctypes import *
libc = cdll.LoadLibrary("libc.dylib")
IntArray5 = c_int * 5
ia = IntArray5(5, 1, 7, 33, 99)
qsort = libc.qsort
qsort.restype = None
class my_int_pointer(object):
@classmethod
def from_param(cls, obj): # not sure it `from_param` is the right place
# in any case, it will not be called, anyway...
return cast(obj, POINTER(c_int))[0]
CMPFUNC = CFUNCTYPE(c_int, my_int_pointer, POINTER(c_int))
def py_cmp_func(a, b):
print "py_cmp_func", a, b[0]
return a - b[0]
cmp_func = CMPFUNC(py_cmp_func)
qsort(ia, len(ia), sizeof(c_int), cmp_func)
但是这并不起作用。
简而言之,我想知道如何定制 ctypes 函数的输入和输出。
__new__
会被调用(如果没有注释掉的话)。 - 101getfunc
被跳过了。调用它只会返回一个普通的 Python 对象,所以为什么要费心呢?话虽如此,子类的__new__
和__init__
方法也不会被调用,因此您无法自定义结果。它通过调用类型的tp_alloc
直接分配对象,然后将结果复制到对象的缓冲区中。 - Eryk Sunint
值并返回一个int
,那么请使用以下函数原型:callback_t = CFUNCTYPE(c_int, c_int, c_int)
。由于c_int
是一个简单的C类型,它的getfunc
将被调用以创建Python函数调用的整数参数。与使用指针的qsort
示例不同,这些参数不会是ctypes类型。 - Eryk Sun