From: Travis O. <oli...@ie...> - 2006-07-03 06:14:09
|
Albert Strasheim wrote: > I did a few tests and this seems to work nicely: > > In [133]: printf = ctypes.cdll.msvcrt.printf > > In [134]: printf.argtypes = [ctypes.c_char_p, ctypes.c_void_p] > > In [135]: x = N.array([1,2,3]) > > In [136]: printf('%p\n', x.ctypes.data) > 01CC8AC0 > Out[136]: 9 > > In [137]: hex(x.__array_interface__['data'][0]) > Out[137]: '0x1cc8ac0' > > It would be nice if we could the _as_parameter_ magic to work as well. See > this thread: > > http://aspn.activestate.com/ASPN/Mail/Message/ctypes-users/3122558 > > 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: > > func.argtypes[n].from_param(x._as_parameter_) > 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 [147]: printf('%p\n', x) > ... > ArgumentError: argument 2: exceptions.TypeError: wrong type > > However, this much works: > > In [148]: ctypes.c_void_p.from_param(x._as_parameter_) > Out[148]: <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 arr.ctypes.data_as() arr.ctypes.strides_as() arr.ctypes.shape_as() 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. -Travis |