How do I convert a Python list into a C array by using ctypes?

59,840

Solution 1

The following code works on arbitrary lists:

import ctypes
py_values = [1, 2, 3, 4]
arr = (ctypes.c_int * len(py_values))(*py_values)

Solution 2

This is an explanation of the accepted answer.

ctypes.c_int * len(pyarr) creates an array (sequence) of type c_int of length 4 (python3, python 2). Since c_int is an object whose constructor takes one argument, (ctypes.c_int * len(pyarr)(*pyarr) does a one shot init of each c_int instance from pyarr. An easier to read form is:

pyarr = [1, 2, 3, 4]
seq = ctypes.c_int * len(pyarr)
arr = seq(*pyarr)

Use type function to see the difference between seq and arr.

Solution 3

From the ctypes tutorial:

>>> IntArray5 = c_int * 5
>>> ia = IntArray5(5, 1, 7, 33, 99)

Solution 4

import ctypes
import typing

def foo(aqs : typing.List[int]) -> ctypes.Array:
    array_type = ctypes.c_int64 * len(aqs)
    ans = array_type(*aqs)
    return ans

for el in foo([1,2,3]):
    print(el)

this will give:

1
2
3
Share:
59,840
No One in Particular
Author by

No One in Particular

Updated on January 04, 2020

Comments

  • No One in Particular
    No One in Particular over 4 years

    If I have the follow 2 sets of code, how do I glue them together?

    void
    c_function(void *ptr) {
        int i;
    
        for (i = 0; i < 10; i++) {
            printf("%p", ptr[i]);
        }
    
        return;
    }
    
    
    def python_routine(y):
        x = []
        for e in y:
            x.append(e)
    

    How can I call the c_function with a contiguous list of elements in x? I tried to cast x to a c_void_p, but that didn't work.

    I also tried to use something like

    x = c_void_p * 10 
    for e in y:
        x[i] = e
    

    but this gets a syntax error.

    The C code clearly wants the address of an array. How do I get this to happen?

  • AaronYC
    AaronYC over 11 years
    "*pyarr" in python... What does it mean?
  • Gabi Purcaru
    Gabi Purcaru over 11 years
    @AaronYC I'm sorry for the confusion; pyarr is an ordinary python list, like pyar = [1,2,3,4]. If you're wondering about the star before the name, check this out: stackoverflow.com/questions/400739/what-does-mean-in-python
  • Pavel Patrin
    Pavel Patrin almost 9 years
    Try to create arrays more than with 255 items.
  • Jiminion
    Jiminion over 7 years
    Good answer, but a bit glib for us unwashed ones.
  • Guillaume Jacquenot
    Guillaume Jacquenot over 7 years
    Works with more than 255 items: IntArray300 = c_int * 300; arrayWith300Elements=IntArray300(*list([i for i in range(300)]))
  • akhan
    akhan almost 6 years
    @Jiminion See my answer below for an explanation of the syntax.
  • Sergiy Kolodyazhnyy
    Sergiy Kolodyazhnyy about 5 years
    Very well, now how would one free that arr variable ? Surely we don't have to use free() from C here do we ?
  • Vishal
    Vishal almost 5 years
    What is the extension of this to produce a 2dim array for a given list like [[1, 2], [3, 4]]?