Passing python list from C to python

John Machin sjmachin at lexicon.net
Tue Jul 14 08:21:30 EDT 2009


On Jul 14, 7:22 pm, hartley <hartle... at gmail.com> wrote:
> > > I'm very new at wrapping Python/C, and I have run into some problems.
[snip]

> > >         pValue = PyObject_CallObject(pFunc,NULL);
>
> > > pValue is now a PyList - i've even verified this with:
>
> > > int a = PyList_Check(pValue);
> > >         printf("%d\n", a);
>
> > > However, I want to send this PyList to another python module,
>
> > Please explain "send" ... do you mean the C equivalent of the Python
> > statement C_embedding.buff = the_pylist ?
>
> > BTW C-embedding would trigger a syntax error in Python source; best to
> > avoid ...
>
> I'm sorry I'm not using the proper terms when trying to describe this
> - i've never really learnt those terms, I guess i should do that one
> day.

Today would be a good day to start :-)

>
> Imagine that the python function C-embedding.buff looks like this:
>
> def buff(a):
>     if isinstance(a,list):
>         print "success"
>
> I want to send, pass, call, whatever a list argument from the C code
> onto this function. As simple as this - how can you call a function in
> python from C, and providing a python list as an argument?
>
> As I wrote earlier - I already have a PyList, called pValue. But I
> have not been able to use this as an argument for C-embedding.buff
> using the code I described last time.
>
> > > but I
> > > don't know how to do this. Initially I though I could just do like
> > > above, only swapping NULL with pValue, but that is not working.
>
> > > pName2 = PyString_FromString("C-embedding");
> > > pModule2 = PyImport_Import(pName2);
> > > pFunc2 = PyObject_GetAttrString(pModule2,"buff");

> >  Any good reason for not checking the
> > return value for an error? [Rhetorical question; answer == "No"]
>
> > > pValue2 = PyObject_CallObject(pFunc2,pValue);

Your problem is here, in the second arg of PyObject_CallObject. It
should be either NULL if no args are being supplied, or a tuple
containing the args if 1 or more args are being supplied. pValue is
the arg itself; you need to wrap it in a tuple.

See http://docs.python.org/c-api/object.html#PyObject_CallObject

Actually you might like to use this instead (no tuple hassles):

http://docs.python.org/c-api/object.html#PyObject_CallFunctionObjArgs

What are you using as a source of information? Have you read this:

http://docs.python.org/extending/embedding.html#pure-embedding ?

It contains a very thorough example of calling a Python function from
C, with all the reference-counting and error-checking stuff and it's
quite runnable -- I've just now compiled it and run it (1) as-is (2)
changed to pass a list instead of multiple ints (3) changed again to
emulate you trying to pass the list directly instead of wrapped in a
tuple ... here's the result:

TypeError: argument list must be a tuple
Call failed

Oh by the way, you can get away with C-embedding as a module name if
you are importing it from C, but importing it from Python [so that you
could test it independently of your C program] presents a difficulty
(syntax error) ... better to change it to c_embedding.

> > It's mainly just a matter of (1) knowing what you want to do (2)
> > picking the API that does what you want (3) checking the returned
> > value for error after every call.

HTH,
John



More information about the Python-list mailing list