Passing python list from C to python

hartley hartley79 at gmail.com
Wed Jul 15 05:54:52 EDT 2009


On Jul 14, 2:21 pm, John Machin <sjmac... at lexicon.net> wrote:
> 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.
>
> Seehttp://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

Thank you, that works! You're a genius :)

As for what I'm reading, I'm familiar with both


http://docs.python.org/c-api/
and
http://docs.python.org/extending/embedding.html#pure-embedding

but i still find it hard to read this and find the proper API. The
Python/C API reference is 162 pages!

I have a second issue that I've also struggled with, namely using
class object (don't shoot me if my terminology is off again). With the
little toy class below, i want to instansiate it, boost it, and return
it, similar to:

s = ObjectTest()
s.boostList()
return s.dispList()

but in C, of course.

so far I have:

pName = PyString_FromString("ob-test");
pModule = PyImport_Import(pName);
pFunc = PyObject_GetAttrString(pModule,"ObjectTest");
if (pFunc && PyCallable_Check(pFunc)) {

            printf("Callable\n");
		}
pObj = PyObject_CallObject(pFunc,NULL);
	if (pObj != NULL) {
	printf("WAS NOT NULL!\n");
}

At least this seems to work. However, as to how to actually
instantiate and use this class the way I described, I have no idea
which API to use. Even though I've spent lots of time reading it! Do
you have any clue here, as well?



(ob-test.py)
class ObjectTest:

	def __init__(self):
		self.list = []


	def boostList(self):
		self.list.append(1)

	def dispList(self):
		return self.list




More information about the Python-list mailing list