I want to
sum_list
of sum a list in c, named sum_list.csum_list.c
file to sum_list.sosum_list = ctypes.CDLL('./sum_list.so')
result = sum_list.sum_list([1, 2, 3])
It raise error in step 4:
ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1
when I write a function in c which add two numbers, it works ok.
so, the point is i don't know how to pass a list (python object) to c.
sum_list.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
long sum_list(PyObject *list)
{
Py_ssize_t i, n;
long total = 0, value;
PyObject *item;
n = PyList_Size(list);
if (n < 0)
return -1; /* Not a list */
for (i = 0; i < n; i++) {
item = PyList_GetItem(list, i); /* Can't fail */
if (!PyLong_Check(item)) continue; /* Skip non-integers */
value = PyLong_AsLong(item);
if (value == -1 && PyErr_Occurred())
/* Integer too big to fit in a C long, bail out */
return -1;
total += value;
}
return total;
}
python code
from ctypes import CDLL
sum_list = CDLL('./sum_list.so')
l = [1, 2, 3]
sum_list.sum_list(l)
I expect the
var
result in my python code is6
.
The ctypes library is meant for calling functions in pure C libraries. The example that you found is for a function that would go into a Python extension module, and be usable without ctypes. Ctypes actually has a type for PyObject *
, namely ctypes.py_object
. You need to wrap the list in this - be careful to ensure that it will stay alive!
In any case you must almost always provide the correct prototype of the function using the restype
and argtypes
.
Here's a working example:
import ctypes
sum_list = ctypes.PyDLL('./sum_list.so')
sum_list.restype = ctypes.c_long
sum_list.argtypes = [ ctypes.py_object ]
l = [1, 2, 3]
print(sum_list.sum_list(ctypes.py_object(l)))
Note, as noticed by Mark, you must use PyDLL
here instead, to ensure that the GIL is not released since the function does not acquire it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With