ctypes

Beware of this little monster in line 2:

>>> from ctypes import *
>>> buf = (c_ubyte * 128*4)()
>>> len(buf)
4
>>> buf = (c_ubyte * 512)()
>>> len(buf)
512

The line 2 and line 5 are not the same! I almost went crazy over this one.

And then here is a seemingly simple thing to do, but took me almost a day to figure out. I have a C function header like this:

void func(unsigned char* buf);

The C library accepts an array, and it will fill this array with values.

And here is my ctypes:

mylib.func.argtypes = [ ctypes.POINTER(ctypes.c_ubyte) ]
mylib.func.restype = None

def testcall():
    p = (c_ubyte *512)()
    print(hex(addressof(p)))
    mylib.func((c_ubyte * len(p)).from_buffer(p))

The intention is that python prepares a byte array of 512 bytes, and then it will be filled-in with values by the the C library. It is simple to look at line 5 and 7 now, but actually coming up to this two lines involved a lot of hair-pulling. When I printed the address at line 6, it matches the buf address when stepping debug into the C code. It's hard to swallow this one, because line 7 looked like a different array is being passed into the func. This one almost ruined Shiloh's birthday.

Last updated

Was this helpful?