Home > Net >  Python ctypes: how to define a callback having a buffer pointer and a length in argument?
Python ctypes: how to define a callback having a buffer pointer and a length in argument?

Time:05-21

I have a lib (in source form, if it helps) defining, among other things the following function:

void subscribe(const char* ip_addr,
               uint16_t port,
               uint32_t token,
               void (*cb)(void *buffer, uint32_t length, uint32_t token)
                  );

I defined this in python (v3.10.4, if it matters):

from ctypes import *

so_file = './mylib.so'
lib = CDLL(so_file)

ADDRESS = b"127.0.0.1"
PORT = 21000

data_callback_type = CFUNCTYPE(None, POINTER(c_byte), c_int32, c_int32)

def py_data_callback(buf, bln, tok):
    print(f'Data: [{hexlify(buf, sep=":", bytes_per_sep=4)}] ({bln}|{tok})')

data_callback = data_callback_type(py_data_callback)
ret = lib.subscribe(c_char_p(ADDRESS), c_uint16(PORT), c_int32(42), data_callback)
print(ret)

...

Registration and callback apparently work fine, but I'm receiving the pointer itself in the callback and not the content (I think that's consistent with what I coded) as printout looks like:

Data: [b'0cc2ddd9:c07f0000'] (24|42)

and b'0cc2ddd9:c07f0000' looks suspiciously similar to a pointer (I'm on an amd64 machine).

How do I convince ctypes to return a bytes(24) or, alternatively, given the above pointer how do I access pointed array?

I am new to ctypes and I could have missed something in the docs, but I didn't find the answer there.

CodePudding user response:

Use ctypes.string_at:

buf_data = ctypes.string_at(buf, bln)

Despite the name, this returns a bytes, not a string

(Source: https://docs.python.org/3/library/ctypes.html)

  • Related