embedding python in C, working but with exception at the end

B

brobigi

well I manage to figure it out myself. I'm using Bloodshed Dev-cpp
Here's the code:


#include "python.h"
#include <stdio.h>

int main(int argc, char* argv[])
{
double answer = 0;
PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;

Py_Initialize();
modname = PyString_FromString("Test");
mod = PyImport_Import(modname);
if (mod)
{
mdict = PyModule_GetDict(mod);
func = PyDict_GetItemString(mdict, "doit"); /* borrowed reference */
if (func)
{
if (PyCallable_Check(func))
{
stringarg = PyString_FromString("5");/*pay attention here*/
args = PyTuple_New(1);
PyTuple_SetItem(args, 0, stringarg);
rslt = PyObject_CallObject(func, args);
if (rslt)
{
answer = PyFloat_AsDouble(rslt);
Py_XDECREF(rslt);
}
Py_XDECREF(stringarg);
Py_XDECREF(args);
}
}

Py_XDECREF(mod);
}

Py_XDECREF(modname);

Py_Finalize();

printf("%g",answer);

return 0;
}

I need to add include and lib directories to the project in order to
everything works fine. Also Test.py is copied in Dev-cpp source code's
folder.
Test file contains the following code

def doit(x1):
try:
x2 = eval(x1)
except:
print 'Error!'
return 0

else:
return x2




However there is an error. Look at the line stringarg =
PyString_FromString("5"); If I put this:
stringarg = PyString_FromString("5+2"); or even this stringarg =
PyString_FromString("5.0");
Program crashes at line Py_Finalize(). Program tries to read some
memory location and suffer run time exception.
Only suggestion is to try to send it to Microsoft.
Why is this happening?
Everything (seems to) works fine I comment line Py_Finalize(), but I
know that this is not a real solution.

Does anybode have a clue what is happening?

Thanks
 
F

Fredrik Lundh

Program crashes at line Py_Finalize(). Program tries to read some
memory location and suffer run time exception.

PyTuple_SetItem "steals" a reference, so changing

Py_XDECREF(stringarg);
Py_XDECREF(args);

to just

Py_XDECREF(args);

might fix the problem.

</F>
 
J

jepler

I see a couple of problems. First, because I'm using Unix, where filenames are
case-sensitive, I had to '#include "Python.h"' instead of '#include
"python.h"'.

Next, it looks like the behavior that '.' is placed on sys.path isn't done
automatically when embedding. So I had to set the environment variable
"PYTHONPATH=." since Test.py was in the current directory.

Before I did this, I got this output:
Exception exceptions.ImportError: 'No module named Test' in 'garbage
collection' ignored
Fatal Python error: unexpected exception during garbage collection
Aborted
which was a clue about the problem you were running into. This ImportError was
being caused back at PyImport_Import but was being transmuted into a fatal
error down at Py_Finalize(). By adding 'else { PyErr_Print(); }' to the end of
'if(mod)', I got the error message printed and cleared. Now, garbage
collection which is kicked off by Py_Finalize() doesn't find the existing error
condition and treat it as a fatal error.

In your code, 'rslt' will be a Python Integer, not a Python Float, so
PyFloat_AsDouble will fail. You could either write something like
if (rslt)
{
if(PyFloat_Check(rslt)) {
answer = PyFloat_AsDouble(rslt);
} else {
printf("not a float\n");
answer = 1.0;
}
Py_XDECREF(rslt);
}
instead, or use PyErr_Check() + PyErr_Print() or PyErr_Clear().
If you want to accept integer or float returns, then maybe you want
if(PyFloat_Check(rslt)) { answer = PyFloat_AsDouble(rslt); }
else if(PyInt_Check(rslt)) { answer = PyInt_AsLong(rslt); }
else probably not a numeric type

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFDGblYJd01MZaTXX0RAopDAJ9WBfDLkPn/LwPLdCO5/71DG2VlXgCbBiK4
mAuoG0sfCNLFxEDVcBoZnag=
=tXJY
-----END PGP SIGNATURE-----
 

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,266
Messages
2,571,318
Members
48,002
Latest member
EttaPfeffe

Latest Threads

Top