66

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?

4 Answers 4

120

The following code works on arbitrary lists:

import ctypes
py_values = [1, 2, 3, 4]
arr = (ctypes.c_int * len(py_values))(*py_values)
Sign up to request clarification or add additional context in comments.

10 Comments

"*pyarr" in python... What does it mean?
@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
Good answer, but a bit glib for us unwashed ones.
@Jiminion See my answer below for an explanation of the syntax.
Very well, now how would one free that arr variable ? Surely we don't have to use free() from C here do we ?
|
25

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.

Comments

13

From the ctypes tutorial:

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

2 Comments

Try to create arrays more than with 255 items.
Works with more than 255 items: IntArray300 = c_int * 300; arrayWith300Elements=IntArray300(*list([i for i in range(300)]))
2
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.