1

I have a ctypes wrapper around an internal library. One of the structures in use has a field called "data" of type POINTER(c_char). This is used to hold the payload of the message (not necessarily a null terminated string). This payload always has an 8 byte header that I would like to skip over. How do you do this in Python with ctypes?

class MyStruct(Structure):
    _fields_ = [("len", c_size_t), ("data", POINTER(c_char))]

def my_cb_proc(msg):
    # want to skip first 8 bytes -- below does not work
    tmp = (POINTER(c_char)).from_address(addressof(msg.contents.data)+8)

    do_something(tmp)
mr19
  • 187
  • 1
  • 15
  • You can slice a pointer: `msg = msg[0]; tmp = msg.data[8:msg.len]`. The value of `tmp` is the byte string starting at byte offset 8. – Eryk Sun Feb 19 '15 at 02:35
  • That returns a item of type 'str'. I need it to be a `POINTER(c_char)` or `c_types.LP_c_char` as `do_something()` uses ctypes to invoke a function in the library that expects a `c_char_p`. – mr19 Feb 19 '15 at 02:42
  • In that case use `msg = msg[0];` `tmp = cast(addressof(msg.data.contents) + 8, POINTER(c_char))`. Or use `POINTER(c_char).from_buffer(c_void_p(addressof(msg.data.contents) + 8))`. – Eryk Sun Feb 19 '15 at 02:49
  • Or use `POINTER(c_char)(c_char.from_address(addressof(msg.data.contents) + 8))`. – Eryk Sun Feb 19 '15 at 03:00
  • Can you see now why what you tried doesn't work? If not, how do you think the `from_address` constructor works? It's literally using the value at the address to construct the object, so whatever is at the address (i.e. your data pointer plus 8) is copied as the address stored in the `POINTER(c_char)` instance, which is meaningless and may even segfault when accessed. – Eryk Sun Feb 19 '15 at 03:07
  • Thanks for response, makes sense. I'm still having issues and I decided to go around the problem by adding a second param `offset` to the `do_something()` function that is passed to the underlying C library. – mr19 Feb 19 '15 at 14:48
  • The 3 ways I showed to create the pointer at the offset work fine. The only thing I wasn't sure about is whether the `msg` parameter is a pointer to the struct, but your example used `msg.contents`, so I guessed it's a pointer and used `msg = msg[0]` to dereference it. – Eryk Sun Feb 19 '15 at 16:10
  • They do seem to work, however when using them to offset the buffer by 8 bytes the underlying library function no longer works. I believe the problem is elsewhere but in the interest of time adding the offset to the library call solves the problem. – mr19 Feb 19 '15 at 17:41

0 Answers0