[Numpy-discussion] Ctypes support in NumPy
oliphant.travis at ieee.org
Mon Jul 3 01:14:05 CDT 2006
Albert Strasheim wrote:
> I did a few tests and this seems to work nicely:
> In : printf = ctypes.cdll.msvcrt.printf
> In : printf.argtypes = [ctypes.c_char_p, ctypes.c_void_p]
> In : x = N.array([1,2,3])
> In : printf('%p\n', x.ctypes.data)
> Out: 9
> In : hex(x.__array_interface__['data'])
> Out: '0x1cc8ac0'
> It would be nice if we could the _as_parameter_ magic to work as well. See
> this thread:
> If I understood Thomas correctly, in the presence of argtypes an an
> instance, say x, with _as_parameter_, the following is done to convert the
> instance to something that the function accepts as its nth argument:
Unfortunately, from the source code this is not true. It would be an
improvement, but the source code shows that the from_param of each type
does something special and only works with particular kinds of
data-types --- basic Python types or ctypes types. I did not see
evidence that the _as_parameter_ method was called within any of the
from_param methods of _ctypes.c
> However, if I try passing x directly to printf, I get this:
> In : printf('%p\n', x)
> ArgumentError: argument 2: exceptions.TypeError: wrong type
> However, this much works:
> In : ctypes.c_void_p.from_param(x._as_parameter_)
> Out: <cparam 'P' (01cc8ac0)>
> So I don't understand why the conversion isn't happening automatically.
Despite any advertisement, the code is just not there in ctypes to do it
when argtypes are present. Dealing with non-ctypes data is apparently
not handled when argtypes are present. Get-rid of the argtypes setting
and it will work (because then the _as_parameter_ method is called....
> Another quirk I noticed is that non-void pointers' from_param can't seem to
> be used with ints. For example:
Yeah from the code it looks like each from_param method has it's own
implementation that expects it's own set of "acceptable" things. There
does not seem to be any way for an object to inform it appropriately.
> I don't think this is too much of an issue though -- you could wrap all your
> functions to take c_void_ps. If you happen to pass an int32 NumPy array to a
> function expecting a double*, you might run into problems though.
Yeah, but you were going to run into trouble anyway. I don't really see
a lot of "value-added" in the current type-checking c-types provides
and would just ignore it at this point. Build a Python function that
calls out to the c-function.
> Maybe there should be a way to get a pointer to the NumPy array data as a
> POINTER(c_double) if it is known that the array's dtype is float64. Ditto
> for c_int/int32 and the others.
I could see value in
methods which allow returning the data as different kinds of c-types
things instead of the defaults --- Perhaps we just make data, strides,
and shapes methods with an optional argument.
More information about the Numpy-discussion