I have a ctypes field that is a POINTER(c_char)
(it had to be, per the documentation, c_char_p didn't work for my application: https://docs.python.org/3.7/library/ctypes.html#ctypes.c_char_p)
For a general character pointer that may also point to binary data, POINTER(c_char) must be used.
However, this usage recommended by ctypes itself seems to have the downside that, it claims to be a pointer to a single character, however, it isn't, it's a pointer to an array of bytes.
How can I read the array returned by the ctypes fucntion (I know the length
) in Python? Trying to index it like foo[0:len]
where foo
is a POINTER(c_char)
blows up with TypeError: 'c_char' object is not subscriptable
I can print the first character of the bytestring using either print(foo)
or print(foo[0])
I was thinking that ctypes.cast
might work, however I don't know how to pass it the length of the cast (as in interpret the first N bytes from address foo as a bytes
object)
EDIT: some code.
So I have a structure:
class foo(Structure):
_fields_ = [("state", c_int),
("type", c_int),
("len", c_int),
("payload", POINTER(c_char))] # according to th following the python bytes are already unsinged https://bytes.com/topic/python/answers/695078-ctypes-unsigned-char
And I have another function that returns a POINTER(foo)
lib3 = CDLL(....so)
f = lib3.f
f.restype = POINTER(foo)
I call f
, which returns a POINTER(foo)
:
ptrf = f(....)
And then I was trying to access ptrf.payload
. The following code works:
def get_payload(ptr_to_foo):
val = cast(ptr_to_foo.contents.payload, c_char_p).value
return val[:ptr_to_foo.contents.len]
So I do
ptrf = f(....)
get_payload(ptrf)
I was wondering whether the get_payload
function would be written more easily.