I am having an issue processing a list of ints passed to a Python C API wrapper function using Python3.6 anaconda distro on a MacOS High Sierra. I would like to convert the list of ints passed in to an array of ints that I can work with in C.
There is a similar question here Passing a Python list to C function using the Python/C API which I can get to work but processing a list of ints appears to be different.
Here is what I have so far.
static PyObject * myModule_sumIt(PyObject *self, PyObject *args) {
PyObject *lst;
if(!PyArg_ParseTuple(args, "O", &lst)) {
Py_DECREF(lst);
return NULL;
}
int n = PyObject_Length(lst);
printf("\nLength of list passed in is %d\n", n);
int nums[n];
int sum = 0;
for (int i = 0; i < n; i++) {
PyLongObject *item = PyList_GetItem(lst, i);
sum += item;
printf("\ni = %d\titem = %d\tsum = %d\n", i, item, sum);
Py_DECREF(item);
}
Py_DECREF(lst);
return Py_BuildValue("i", sum);
}
static PyMethodDef methods[] = {
{ "sum_it", myModule_sumIt, METH_VARARGS, "A Toy Example" },
{ NULL, NULL, 0, NULL }
};
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"myModule",
"Demo Python wrapper",
-1,
methods
};
PyMODINIT_FUNC PyInit_myModule(void) {
return PyModule_Create(&myModule);
}
This is what I get from calling the python function in the interpreter after building with distutils.
>>> import myModule
>>> myModule.sum_it([1,2,3])
Length of list passed in is 3
i = 0 item = 108078416 sum = 890306742
i = 1 item = 108078448 sum = 890306742
i = 2 item = 108078480 sum = 890306742
-1725230192
Note that my expected output should be
>>> import myModule
>>> myModule.sum_it([1,2,3])
Length of list passed in is 3
i = 0 item = 1 sum = 1
i = 1 item = 2 sum = 3
i = 2 item = 3 sum = 6
6
sum += item;
item
is not a C long or int! You have to use PyLong_AsLong
:
sum += PyLong_AsLong(item);
(And sum
should be a long
)