I understand that multiplying a ctype with an integer is declaring an array.
For example, ctypes.c_int * 4 is an array of 4 integers.
Then what is py_object?
Please help me understand how does ctypes.c_int differs from ctypes.py_object?
Trying to execute
will generate a
TypeError: an integer is required (got type str).This is because we have specified that we want an array of three elements, all of which are integers, but we have attempted to include a string inside the array as well.
Arrays, unlike lists, require that all elements
a[0], a[1], ... , a[n]are of the same type.By specifying
py_objectinstead ofc_int, you are essentially permitted to have an array of arbitrary Python objects, as opposed to only integers.Strictly speaking (in CPython), internally, the
py_objectway gives you an array of pointers to thePyObjectdatatype. Internally, all object types are extensions ofPyObject.So the type of all the elements of the
barray is pointer toPyObject. A pointer is nothing more than a memory address. So every element of thebarray is just a memory address pointing to some arbitrary object in Python. Internally, integer, floats, lists, dictionaries, and so on are allPyObjects so an array with elements of typepy_objectallows for its elements to be memory addresses that refer to essentially any kind of object in Python (lists, tuples, integers, floats, and so on).When we print
b[0], for example, Python gives us'Pizza'as output. Internally, Python uses the memory address of the string object and returns the string for us.Pointers / memory addresses are used frequently in C and in the CPython source code. Python essentially hides memory addresses from us as it is a high-level language, abstracting away from low-level concepts such as pointers.
I hope this helps!