Help with C API

N

Nick Jacobson

In the Python Cookbook, Luther Blisset wrote a very useful class with
the Python C API. It takes a Python list of elements and copies it
member by member into a C array.

Here it is, (slightly modified by me):

static PyObject *totaldoubles(PyObject *self, PyObject *args) {
PyObject *seq, *item, *fitem;
double *dbar, result;
int i, seqlen;

if (!PyArg_ParseTuple(args, "O", &seq)) return NULL;
seq = PySequence_Fast(seq, "argument must be iterable");
if (!seq) return NULL;

seqlen = PySequence_Fast_GET_SIZE(seq);
dbar = malloc(seqlen * sizeof(double));
if (!dbar) { Py_DECREF(seq); return NULL; }

for (i=0; i < seqlen; i++) {
item = PySequence_Fast_GET_ITEM(seq, i);
if (!item) { Py_DECREF(seq); free(dbar); return NULL; }
fitem = PyNumber_Float(item);
if (!fitem) { Py_DECREF(seq); free(dbar); return NULL; }
dbar = PyFloat_AS_DOUBLE(fitem);
Py_DECREF(fitem);
}

Py_DECREF(seq);
result = total(dbar, seqlen); /*call a C function using this array*/
free(dbar);
return Py_BuildValue("d", result);
}

I'd like to do the reverse: take an C array (say, with 100 elements)
and copy its elements into a Python list. But I don't know where to
start...there's no PySequence_Fast_INSERT or even PySequence_Insert
function, for example. Can I create an empty list in the API or
should I just pass one in from Python?

Can someone please help with this? Thanks in advance!!

--Nick
 
V

vincent wehren

Nick Jacobson wrote:
....
I'd like to do the reverse: take an C array (say, with 100 elements)
and copy its elements into a Python list. But I don't know where to
start...there's no PySequence_Fast_INSERT or even PySequence_Insert
function, for example. Can I create an empty list in the API or
should I just pass one in from Python?

Can someone please help with this? Thanks in advance!!

--Nick

http://docs.python.org/api/listObjects.html is probably a good start

Regards,
Vincent Wehren
 
N

Nick Jacobson

vincent wehren said:
Nick Jacobson wrote:
...

http://docs.python.org/api/listObjects.html is probably a good start

Regards,
Vincent Wehren


Thank you!

This is what I ended up writing:

static PyObject *ex_arytopylist(PyObject *self, PyObject *args) {
PyObject *seq = NULL, *fitem = NULL;
double dbar[] = { 1, 2, 3 };
int i, seqlen = sizeof(dbar) / sizeof(double);

seq = PyList_New(0);
if (!seq) return NULL;

for (i=0; i < seqlen; i++) {
fitem = PyFloat_FromDouble(dbar);
if (!fitem) { Py_DECREF(seq); return NULL; }
if (PyList_Append(seq, fitem))
{ Py_DECREF(fitem); Py_DECREF(seq); return NULL; }
Py_DECREF(fitem);
}
return Py_BuildValue("O", seq);
}

My only question is, since PyList_New(0) and Py_BuildValue both
increment the ref count of seq, is it garbage collected properly? Or
perhaps I should just write:

return seq;

Thanks!
 
N

Nick Jacobson

I don't think I'm stating my question clearly. :(

Say I create a list in my C function:
seq = PyList_New(0);
Then append some numbers to it, whatever.

Then, when I return from the C function and want to use that list in
my Python code, do I have to increment its refcount:
return Py_BuildValue("O", seq);

Or do I leave it alone and say:
return seq;

Thanks in advance.
 
J

John E. Barham

Nick Jacobson said:
I don't think I'm stating my question clearly. :(

Say I create a list in my C function:
seq = PyList_New(0);
Then append some numbers to it, whatever.

Then, when I return from the C function and want to use that list in
my Python code, do I have to increment its refcount:
return Py_BuildValue("O", seq);

Or do I leave it alone and say:
return seq;

Thanks in advance.

Grepping through the modules shipped w/ Python seems to suggest that you
should just return it since calling PyList_New() returns a new reference.
See for example its use in the strop module (http://tinyurl.com/25s4e) which
does something similar to what you describe.

HTH,

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top