When wrapping Python functions with a CFUNCTYPE
type, I've found that the non-pointer types are automatically converted as though their value
attribute was called.
How can I suppress this automatic conversion?
from ctypes import *
funcspec = CFUNCTYPE(c_int, c_int, POINTER(c_int))
@funcspec
开发者_JS百科def callback(the_int, the_int_p):
print(vars())
return 3
print(callback(c_int(1), byref(c_int(2))))
Which produces (python3
cfunctype_type_conversion.py
):
{'the_int': 1, 'the_int_p': <__main__.LP_c_int object at 0x2671830>}
3
I'd like:
{'the_int': c_int(1), 'the_int_p': <__main__.LP_c_int object at 0x2671830>}
c_int(3)
This is a bit of a hack, but it might work for you. Hopefully someone else will chime in with a cleaner way..
from ctypes import *
class c_int_hack(c_int):
def from_param(self, *args):
return self
funcspec = CFUNCTYPE(c_int, c_int_hack, POINTER(c_int))
@funcspec
def callback(the_int, the_int_p):
print(vars())
print(the_int.value)
return 3
print(callback(c_int(1), byref(c_int(2))))
..and the output is:
{'the_int': <c_int_hack object at 0xb7478b6c>, 'the_int_p': <__main__.LP_c_long object at 0xb747892c>}
1
3
I've been looking at the ctypes code recently, thought I might be able to figure this one out. The c code that does this is in callproc.c (here's the source for 2.7.2).
A relevant comment from the source:
5. If 'converters' are present (converters is a sequence of argtypes' from_param methods), for each item in 'callargs' converter is called and the result passed to ConvParam. If 'converters' are not present, each argument is directly passed to ConvParm.
Which is pretty much what Luke said, so what he gave is probably not a hack.
精彩评论