Subclasses of ctypes types

I was wondering if different types of ctypes can be subclassed. I tried to write a simple example, but there are one (or two) things that I do not understand.

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!")

Why my_c_intdoesn’t it return the same type as the original one c_int, namely int? Can this be done? If I write print printf(...).value, it works. Is it possible to automatically return .valuefor my_c_int?

PS: Btw., Why is the method __new__not called?


Edit:

Consider another example from the docs:

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)

Ok, that works. My question is: is it possible to change the arguments received by the function CMPFUNC? Can this be done using any type / type of a subclass of the type?

For example, let's say I wanted to pass in py_cmp_funcintegers directly (and not pointers). I could do:

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)

, , . auxiliary? :

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.

+4
1

, , Python 2.7.6:

from ctypes import *
class my_c_int(c_int):
    def __new__(*args):
        print 'new!'
my_c_int()   # prints 'new!'
0

All Articles