Calling C from Python: Passing a List of Numpy Pointers

I have a variable number of numpy arrays that I would like to pass to C. I managed to pass each individual array (using <ndarray>.ctypes.data_as(c_void_p)), but the number of arrays can vary greatly.

I thought I could pass all these “pointers” in the list and use the function PyList_GetItem()in the C code. It works like a charm, except that the values ​​of all the elements are not pointers, which I usually get when they are passed as arguments to the function.

Although, if I have:

from numpy import array
from ctypes import py_object

a1 = array([1., 2., 3.8])
a2 = array([222.3, 33.5])

values = [a1, a2]

my_cfunc(py_object(values), c_long(len(values)))

And my C code looks like this:

void my_cfunc(PyObject *values)
{
    int i, n;

    n = PyObject_Length(values)
    for(i = 0; i < n; i++)
    {
        unsigned long long *pointer;
        pointer = (unsigned long long *)(PyList_GetItem(values, i);
        printf("value 0 : %f\n", *pointer);
    }
}

The printed value is 0.0000

, ctypes.byref(), ctypes.pointer() .. . , , c_void_p(), 32 ...

numpy C, c_types Python ( , ...).

?

+4
1

, include, - , . , , - .

:

numpy, Python C

( , , , C- Python)

Numpy Python C , C. - Python

from numpy import array
from ctypes import c_long

values = array([1.0, 2.2, 3.3, 4.4, 5.5])

my_c_func(values.ctypes.data_as(c_void_p), c_long(values.size))

C :

void my_c_func(double *value, long size)
{
    int i;
    for (i = 0; i < size; i++)
        printf("%ld : %.10f\n", i, values[i]);
}

... , ? , , ( Stackoverflow), - .

C, C- .

, , ... , ! :

/tuple/dictionary - Python... C !

, , , . , :-) , Python:

from numpy import array

my_list = (array([1.0, 2.2, 3.3, 4.4, 5.5]),
           array([2.9, 3.8. 4.7, 5.6]))

my_c_func(py_object(my_list))

, , , PyObject.

C.

void my_c_func(PyObject *list)
{
    int i, n_arrays;

    // Get the number of elements in the list
    n_arrays = PyObject_Length(list);

    for (i = 0; i LT n_arrays; i++)
    {
        PyArrayObject *elem;
        double *pd;

        elem = PyList_GetItem(list,
                              i);
        pd = PyArray_DATA(elem);
        printf("Value 0 : %.10f\n", *pd);
    }
}

:

  • PyObject
  • PyObject_Length().
  • PyList_GetItem() PyObject ( a void *)
  • PyArray_DATA().

PyList_GetItem() PyObject *, Python.h ndarraytypes.h, , ( !):

typedef struct _object {
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
} PyObject;

PyArrayObject... . , . ob_type , Python. , . struct tp_name - , ... ; , ! , .

, ndarray? ... , , , ob_type. PyArray_DATA() :

#define PyArray_DATA(obj) ((void *)((PyArrayObject_fields *)(obj))->data)

PyArayObject * PyArrayObject_fields *, ( !):

typedef struct tagPyArrayObject_fields {
    Py_ssize_t ob_refcnt;
    struct _typeobject *ob_type;
    char *data;
    int nd;
    npy_intp *dimensions;
    npy_intp *strides;
    PyObject *base;
    PyArray_Descr *descr;
    int flags;
    PyObject *weakreflist;
} PyArrayObject_fields;

, , PyObject PyArrayObject, . , , , . . , .

, PyArrayObject http://docs.scipy.org/doc/numpy/reference/c-api.array.html

, PyArrayObject PyArray_SIZE(PyArrayObject *)

, , : -)

+3

All Articles