Ctypes pointer to c_int vs array c_ints

I am trying to call a function in a dll. This function is called pop()

and takes two parameters: an int and a pointer to int. The first parameter is the length of the array that starts with the second parameter. This function should return a pointer to int, which is the first element in the array of elements n-1

, where n

is the number of elements in the original array. The returned array must be the original array without the 0th element.

My code:

from ctypes import cdll, c_int, POINTER

lib = cdll.LoadLibrary('extlib.dll')

lib.pop.restype = POINTER(c_int)
#lib.pop.restype = c_int*4

testArray = (c_int*5)(*[5,6,7,8,9])
output = list(lib.pop(5, testArray)[0:4])

print output


When run as is, it produces the following (expected) output:

[6, 7, 8, 9]


If I uncomment the commented line and comment out the line above, I get this (unexpected) output:

[6618688, 0, 2, 0]


It looks like the types c_int*4

and are POINTER(c_int)

different, as I believe this is all I changed. However, the Python documentation seems to suggest that they should be the same. What's going on here? In particular, why don't the two versions of the code work the same way?


source to share

1 answer

>>> platform.architecture()
('64bit', 'WindowsPE')
>>> ctypes.sizeof(ctypes.c_int*4)
>>> ctypes.sizeof(ctypes.POINTER(ctypes.c_int))


It is clear that these are different entities. In particular, an array cannot be returned from a C function because it does not fit into a register.

In the second case, your result is your returned int*

somewhere, stored ctypes

and interpreted as int[4]

: the first is your pointer as well as some garbage at the following addresses. On x64, the first is one DWORD address, the next is another DWORD (which depends on your entity), the rest are garbage.



All Articles