Embedding Python in C

M

mistabean

Hello,

first of all, I am a programming newbie, especially in python...

Onwards to the problem, I have been having difficulty embedding a
python module into my C/C++ program. (just a test program before
moving on into the real thing). I have been making test runs using the
codes from http://docs.python.org/ext/pure-embedding.html as a basic,
but modifiying it now as a function inside my C/C++ code.

Problem started when I started passing an array as an argument. The
module also need an array as an argument, but somehow I can't make
them to go pass the "input-error checking" of the module.

The code for argument building and calling are as follows:

void CallSnake(char ModName[], char FuncName[], double result[])
{
...
/*Some operations to import modname, and preping FuncName, all is
ok*/
...
/*Processing the result array and calling the function, problem
time*/
pArgs = PyTuple_New(MAX_ELEMENT);
pArg = PyList_New(1);
for (i = 0; i < MAX_ELEMENT; ++i)
{
pValue = Py_BuildValue("d", result);
PyTuple_SetItem(pArgs, i, pValue);

if (!(*pArgs).ob_refcnt)
{
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return;
}
}

PyList_SetItem(pArg, 0, pArgs);
pValue = PyObject_CallFunctionObjArgs(pFunc,pArg,NULL);
/*Some more checking and DECREFing occurs here*/
}

Error I have been getting is:

Traceback
if x.ndim != 1; /*x is the input array, checking if it's a 1D*/
AttributeError: 'list' object has no attribute 'ndim'

I have been trying many call variations, but alas, I think the problem
lies in the list building process. I have no problems calling a non-
arrayed (albeit,still single) argument.

Thanks in advance...
 
G

Gabriel Genellina

Onwards to the problem, I have been having difficulty embedding a
python module into my C/C++ program. (just a test program before
moving on into the real thing). I have been making test runs using the
codes from http://docs.python.org/ext/pure-embedding.html as a basic,
but modifiying it now as a function inside my C/C++ code.

Problem started when I started passing an array as an argument. The
module also need an array as an argument, but somehow I can't make
them to go pass the "input-error checking" of the module.

The code for argument building and calling are as follows:

void CallSnake(char ModName[], char FuncName[], double result[])
{
...
/*Some operations to import modname, and preping FuncName, all is
ok*/
...
/*Processing the result array and calling the function, problem
time*/
pArgs = PyTuple_New(MAX_ELEMENT);

Should check for a NULL return value.
pArg = PyList_New(1);

Same here.
for (i = 0; i < MAX_ELEMENT; ++i)
{
pValue = Py_BuildValue("d", result);


I'd use PyFloat_FromDouble here.
PyTuple_SetItem(pArgs, i, pValue);

if (!(*pArgs).ob_refcnt)

What do you expect from this? pArgs is a newly created tuple - unless you
DECREF it explicitely, ob_refcnt should never be 0. (Also, the -> operator
exists for exactly this usage).
PyList_SetItem(pArg, 0, pArgs);
pValue = PyObject_CallFunctionObjArgs(pFunc,pArg,NULL);

You didn't show us how you got pFunc here. Just to make it clear, you are
calling pFunc with a single argument, which is a list that contains a
single element, which is a tuple containing exactly MAX_ELEMENT float
objects.
Traceback
if x.ndim != 1; /*x is the input array, checking if it's a 1D*/
AttributeError: 'list' object has no attribute 'ndim'

Python lists don't have a ndim attribute. Perhaps you want some kind of
Numeric array? (ndarray?)
I have been trying many call variations, but alas, I think the problem
lies in the list building process. I have no problems calling a non-
arrayed (albeit,still single) argument.

Yes, it appears that you are building a plain list but your code is
expecting another kind of object. I'm unfamiliar with Numeric arrays, if
that is what you need; perhaps someone else can help, or ask again in a
Numeric-specific list.
 
M

mistabean

En Mon, 04 Jun 2007 11:58:38 -0300, <[email protected]> escribió:




Onwards to the problem, I have been having difficulty embedding a
python module into my C/C++ program. (just a test program before
moving on into the real thing). I have been making test runs using the
codes fromhttp://docs.python.org/ext/pure-embedding.htmlas a basic,
but modifiying it now as a function inside my C/C++ code.
Problem started when I started passing an array as an argument. The
module also need an array as an argument, but somehow I can't make
them to go pass the "input-error checking" of the module.
The code for argument building and calling are as follows:
void CallSnake(char ModName[], char FuncName[], double result[])
{
...
/*Some operations to import modname, and preping FuncName, all is
ok*/
...
/*Processing the result array and calling the function, problem
time*/
pArgs = PyTuple_New(MAX_ELEMENT);

Should check for a NULL return value.
pArg = PyList_New(1);

Same here.
for (i = 0; i < MAX_ELEMENT; ++i)
{
pValue = Py_BuildValue("d", result);


I'd use PyFloat_FromDouble here.
PyTuple_SetItem(pArgs, i, pValue);
if (!(*pArgs).ob_refcnt)

What do you expect from this? pArgs is a newly created tuple - unless you
DECREF it explicitely, ob_refcnt should never be 0. (Also, the -> operator
exists for exactly this usage).
PyList_SetItem(pArg, 0, pArgs);
pValue = PyObject_CallFunctionObjArgs(pFunc,pArg,NULL);

You didn't show us how you got pFunc here. Just to make it clear, you are
calling pFunc with a single argument, which is a list that contains a
single element, which is a tuple containing exactly MAX_ELEMENT float
objects.
Traceback
if x.ndim != 1; /*x is the input array, checking if it's a 1D*/
AttributeError: 'list' object has no attribute 'ndim'

Python lists don't have a ndim attribute. Perhaps you want some kind of
Numeric array? (ndarray?)
I have been trying many call variations, but alas, I think the problem
lies in the list building process. I have no problems calling a non-
arrayed (albeit,still single) argument.

Yes, it appears that you are building a plain list but your code is
expecting another kind of object. I'm unfamiliar with Numeric arrays, if
that is what you need; perhaps someone else can help, or ask again in a
Numeric-specific list.


yeah, i was looking at am array full of numbers. import numpy,scipy,
maybe pylab too while i was testing out the function over at a python
shell, make a linspace, sin it, and then call the function (which also
is from the scipy cookbook). Is numeric arrays (or ndarray) unlike
normal listing then? Since I started off programming in C, I am having
a bit of a confusion identifiying the different type of arrays,
listing and tuples and such... (since it's just "build an array of
type so and so, and pass it over" ^^;;)

the reason i didn't show pFunc is that because it is the result of
operations done to FuncName (ModName = module to be imported, FuncName
= function to be called), therefore i feel it would be a bit waste of
time/space to put in the pFunc function, since I didn't change the
operations concerning pFunc other than changing argv[1] to FuncName
from the link i gave (and not the core of my problem).

so yeah, maybe I am building and passing the array/calling the
function the wrong way... will have to take a look at numpy/numerical
specific C API and stuff now

thanks for your time and the help
 
M

mistabean

now then... where's the edit button...?

oh well, double-posting. Problem solved, thanks for pointing out that
I am needing a numeric array built instead of building a normal list/
tuple. For those who are curious, steps to solving:

....
#include "libnumarray.h" /*from numpy*/
....
....
....

void CallSnake(...)
{
....
....
Py_Initialize();
import_libnumarray(); /*badgered me to call this one... where i don't
know*/
....
....
pArray = NA_InputArray(pArgs, tFloat32, NUM_C_ARRAY); /*instead of
making a pArg and calling PyList_SetItem(pArg, 0, pArgs); */

/*Check for NULL on pArray*/

pValue = PyObject_CallFunctionObjArgs(pFunc,pArray,NULL);
/*error checking, cleaning up, Finalizing etc etc*/
}
 
G

Gabriel Genellina

yeah, i was looking at am array full of numbers. import numpy,scipy,
maybe pylab too while i was testing out the function over at a python
shell, make a linspace, sin it, and then call the function (which also
is from the scipy cookbook). Is numeric arrays (or ndarray) unlike
normal listing then? Since I started off programming in C, I am having
a bit of a confusion identifiying the different type of arrays,
listing and tuples and such... (since it's just "build an array of
type so and so, and pass it over" ^^;;)

I've seen that you have already solved your main problem, but anyway I'll
try to reduce your confusion a little...
Python lists and tuples are "generic" containers: both can contain any
kind of object, and each item may be of a different type: (1, 2.0, 3+0j,
"four", u"Fünf", file("six")) is a tuple containing 6 items, all of
different types. Tuples are immutable, lists can be modified.
There is a price for such flexibility: memory and time overhead. When you
don't require flexibility, you don't have to pay the price; Python already
provides simple array objects (a flat container where ALL items are of the
same type) and Numeric&Co support more array types and different floating
point numbers.
Those arrays are not the same thing as lists/tuples - altough they share a
very similar interfase.
 
M

mistabean

Python lists and tuples are "generic" containers: both can contain any
kind of object, and each item may be of a different type: (1, 2.0, 3+0j,
"four", u"Fünf", file("six")) is a tuple containing 6 items, all of
different types. Tuples are immutable, lists can be modified.
There is a price for such flexibility: memory and time overhead. When you
don't require flexibility, you don't have to pay the price; Python already
provides simple array objects (a flat container where ALL items are of the
same type) and Numeric&Co support more array types and different floating
point numbers.
Those arrays are not the same thing as lists/tuples - altough they share a
very similar interfase.

Hmmmm, interesting to know that multi-type...errr... "thingys" can be
packed into one tuple or list. I think my problem of not recognizing
what array is what type will be solved in time *hopefully*.

Joe Riopel said:
This seems like a pretty good resource, although I didn't read it all yet:
http://www.ibm.com/developerworks/edu/l-dw-linux-pythonscript-i.html

Thanks for the link. Every resource is useful, in one way or another.
 

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
474,262
Messages
2,571,048
Members
48,769
Latest member
Clifft

Latest Threads

Top