Message267992
Probably adding from_pointer is a good idea. That said, there's a simpler way to go about getting a bytes copy for a pointer.
Say that you have a pointer p for the following array:
>>> a = (c_float * 3)(1, 2, 3)
>>> bytes(a)
b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@'
>>> p = POINTER(c_float)(a)
IMO, the most straight-forward way to get a bytes copy is to call string_at:
>>> string_at(p, sizeof(p.contents) * 3)
b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@
In 3.x string_at uses the FFI machinery to call the following function:
static PyObject *
string_at(const char *ptr, int size)
{
if (size == -1)
return PyBytes_FromStringAndSize(ptr, strlen(ptr));
return PyBytes_FromStringAndSize(ptr, size);
}
The first argument can be any type accepted by c_void_p.from_param, such as a ctypes pointer/array, str, bytes, or an integer address.
Alternatively, note that pointer instantiation is the same as setting the `contents` value, which accepts any ctypes data object. Here's the C code that implements this assignment:
dst = (CDataObject *)value;
*(void **)self->b_ptr = dst->b_ptr;
The b_ptr field points at the buffer of the ctypes data object. Thus you can cast p to a char pointer without even calling the cast() function, which avoids an FFI call:
>>> bp = POINTER(c_char)(p.contents)
Slicing c_char and c_wchar pointers is special cased to return bytes and str, respectively. So you can slice bp to get bytes:
>>> bp[:sizeof(p.contents) * 3]
b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@' |
|
Date |
User |
Action |
Args |
2016-06-09 08:32:49 | eryksun | set | recipients:
+ eryksun, amaury.forgeotdarc, belopolsky, memeplex, meador.inge |
2016-06-09 08:32:49 | eryksun | set | messageid: <1465461169.56.0.491626679894.issue27274@psf.upfronthosting.co.za> |
2016-06-09 08:32:49 | eryksun | link | issue27274 messages |
2016-06-09 08:32:49 | eryksun | create | |
|