On Thu, Apr 12, 2018 at 11:25 PM, Gregory Ewing <greg.ew...@canterbury.ac.nz> wrote: > > To get around this, you may need to declare the return type > as POINTER(c_char) instead: > >> For a general character pointer that may also point to binary data, > >> POINTER(c_char) must be used. > > I'm not sure where to go from here, though, because the > ctypes documentation peters out before explaining exactly > what can be done with a POINTER object.
Pointers can be indexed and sliced. You have to be careful, however, since there's no bounds checking. Alternatively, without copying, you can create an array view on the buffer, which is bounded and thus doesn't risk an access violation (segfault). For example: Say the function returns a pointer to a buffer with the contents b"spam\x00". Let's simulate the function result using a void * pointer to initialize a char * pointer: >>> buf0 = ctypes.create_string_buffer(b'spam') >>> pvoid = ctypes.c_void_p(ctypes.addressof(buf0)) >>> result = ctypes.POINTER(ctypes.c_char).from_buffer_copy(pvoid) This pointer object has just the address of the buffer, without supporting references in _b_base_ or _objects: >>> result._b_base_ is result._objects is None True (In other words, ctypes isn't responsible for the buffer, as simulated here. Libraries that allocate their own memory for results have to provide a function to free it. Especially on Windows, you cannot rely on both Python and the DLL to use the same heap.) You can slice the pointer: >>> result[:5] b'spam\x00' Or you can access the buffer more safely as a new array view: >>> array_t = ctypes.c_char * 5 >>> pointer_t = ctypes.POINTER(array_t) >>> result.contents c_char(b's') >>> buf1 = pointer_t(result.contents)[0] >>> buf1[:] b'spam\x00' This buf1 array is a view on the buffer, not a copy. It reflects whatever changes are made to the underlying buffer: >>> buf0[:] = b'eggs\x00' >>> buf1[:] b'eggs\x00' As such, ctypes knows it doesn't have to free this memory: >>> buf1._b_needsfree_ 0 -- https://mail.python.org/mailman/listinfo/python-list