Let's combine all of the examples above into one complex scenario: using libc
's lfind
function.
For more details about the function, read the man page. I urge you to read it before going on.
First, we'll define the proper prototypes:
>>> compar_proto = CFUNCTYPE(c_int, POINTER(c_int), POINTER(c_int))
>>> lfind_proto = CFUNCTYPE(c_void_p, c_void_p, c_void_p, POINTER(c_uint), c_uint, compar_proto)
Then, let's create the variables:
>>> key = c_int(12)
>>> arr = (c_int * 16)(*range(16))
>>> nmemb = c_uint(16)
And now we define the comparison function:
>>> def compar(x, y):
return x.contents.value - y.contents.value
Notice that x
, and y
are POINTER(c_int)
, so we need to dereference them and take their values in order to actually compare the value stored in the memory.
Now we can combine everything together:
>>> lfind = lfind_proto(libc.lfind)
>>> ptr = lfind(byref(key), byref(arr), byref(nmemb), sizeof(c_int), compar_proto(compar))
ptr
is the returned void pointer. If key
wasn't found in arr
, the value would be None
, but in this case we got a valid value.
Now we can convert it and access the value:
>>> cast(ptr, POINTER(c_int)).contents
c_long(12)
Also, we can see that ptr
points to the correct value inside arr
:
>>> addressof(arr) + 12 * sizeof(c_int) == ptr
True