Re: [ctypes-users] Dereferencing a slice of pointer
Brought to you by:
theller
|
From: Thomas H. <th...@py...> - 2004-07-09 20:08:54
|
Holger Duerer <H.D...@gm...> writes: > I am currently trying to wrap a function which allocates a buffer for > me; something like > ,---- > | int foo(char **out_buffer, size_t *out_buffer_length); > `---- > > The data in the buffer can be binary, i.e. it may contain a 0-byte, > which is why we get a length returned as well. > > Because of the 0-byte, I cannot use something like > > ,---- > | out_buffer = c_char_p() > | out_buffer_length = c_int() > | success = the_lib.foo(byref(out_buffer), byref(out_buffer_length)) > `---- > > What I currently have is: > ,---- > | out_buffer = POINTER(c_char)() > | out_buffer_length = c_int() > | success = the_lib.foo(pointer(out_buffer), byref(out_buffer_length)) > | out_buffer = "".join([out_buffer[i] for i in range(out_buffer_length)]) > `---- > and this works. > > Two questions: > a) Could this be done better? No, it's the 'correct' way to do it, but let me make two remarks. You could use byref(out_buffer) in the the_lib.foo call instead of pointer(out_buffer), this will be slightly faster. And it seems in your code the pointer can never be freed because you overwrite the out_buffer variable. Maybe you were just simplifying... > b) Why doesn't the pointer metaclass support slicing? I.e. this could > have simplified my last line to > ,---- > | out_buffer = "".join(out_buffer[:out_buffer_length]) > `---- > I had a quick glance at the code and it is just missing -- is this > intentional or just not yet done? I probably had a mental block (Brett vor'm Kopf) because I always thought about slicing support for arrays instead of pointers first. And I couldn't decide if it would be better to return a new ctypes array instance as the slice, or a list of array elements. The array instance would be much more complicated, because this would have to be an instance of a probably not yet existing class. For pointer slicing, it is simpler because an array would not make any sense. So I think the list of elements is what needs to be returned, for pointers *and* for arrays. Same for slice assignment, of course. Oh, and for arrays or pointers of c_chars it could be specialized to return a string instead of a list of characters instead, so that you could write ,---- | out_buffer = out_buffer[:out_buffer_length] `---- instead of the join above. Sounds good? Thanks, Thomas |