How to convert a Python 'bytes' object to ctypes 'POINTER(c_byte)'
Question:
I want to write a ctypes wrapper for a C function with this signature:
int utp_process_udp(utp_context *ctx, const byte *buf, size_t len, const struct sockaddr *to, socklen_t tolen);
And to have some type checking I’ve added this to my Python wrapper:
libutp.utp_process_udp.argtypes = [POINTER(UtpContext), POINTER(c_byte), c_size_t, POINTER(sockaddr_in), c_int]
But when I pass a bytes
object as the buf
argument I get this error:
Traceback (most recent call last):
File "ucat.py", line 269, in <module>
main()
File "ucat.py", line 251, in main
network_loop()
File "ucat.py", line 138, in network_loop
utp.utp_process_udp(ctx, data, addr)
File "/home/mostafa/source/pyutp/utp.py", line 159, in utp_process_udp
POINTER(c_byte)(data), c_size_t(len(data)),
TypeError: expected c_byte instead of bytes
If I don’t set argtypes
I can successfully call the function though, so obviously the bytes
object can be passed to this function. Is there anything I should do to let ctypes know what I’m doing? Some sort of cast perhaps? (I have tried using the ctypes.cast
function but that did not work.)
Answers:
I just used POINTER(c_char)
instead of POINTER(c_byte)
and the problem went away.
I frequently use: ctypes.POINTER(ctypes.c_byte)
I want to write a ctypes wrapper for a C function with this signature:
int utp_process_udp(utp_context *ctx, const byte *buf, size_t len, const struct sockaddr *to, socklen_t tolen);
And to have some type checking I’ve added this to my Python wrapper:
libutp.utp_process_udp.argtypes = [POINTER(UtpContext), POINTER(c_byte), c_size_t, POINTER(sockaddr_in), c_int]
But when I pass a bytes
object as the buf
argument I get this error:
Traceback (most recent call last):
File "ucat.py", line 269, in <module>
main()
File "ucat.py", line 251, in main
network_loop()
File "ucat.py", line 138, in network_loop
utp.utp_process_udp(ctx, data, addr)
File "/home/mostafa/source/pyutp/utp.py", line 159, in utp_process_udp
POINTER(c_byte)(data), c_size_t(len(data)),
TypeError: expected c_byte instead of bytes
If I don’t set argtypes
I can successfully call the function though, so obviously the bytes
object can be passed to this function. Is there anything I should do to let ctypes know what I’m doing? Some sort of cast perhaps? (I have tried using the ctypes.cast
function but that did not work.)
I just used POINTER(c_char)
instead of POINTER(c_byte)
and the problem went away.
I frequently use: ctypes.POINTER(ctypes.c_byte)