[capi-sig] Easy way to Return Value from 1 line of Embedded Python?
Jerry Krinock
support at sheepsystems.com
Thu May 27 16:26:39 CEST 2010
In a C program I need to unpickle a Python pickle which is generated by someone's Python program. A Python newbie, I was able to do this, but only by writing a little python script file and loading it as a module. But reading from a script file is fragile, has lots of possible errors to handle as you can see below, and is silly since there's only one line of Python.
I'd therefore like to create the Python module from a string constant, as with PyRun_SimpleString(), instead of reading a file. But I can't find a function like that which returns a value. Or I just don't know how.
Certainly there must be a simpler way to do this...
Thank you,
Jerry Krinock
***** somePython.py *****************************
#!/usr/bin/env python
from pickle import loads
def unpickle(x):
return loads(x)
***** My C "Proof of Concept" Function **********
#include <Python/Python.h> // Running on Mac OS X
char* PythonUnpickle(char* pickle) {
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue;
char* unpickledString = NULL ;
Py_Initialize();
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\"/Users/jk/Documents/Programming/Python/\")");
pName = PyString_FromString("somePython");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, "unpickle");
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(1);
// Create the argument to unpickle()
pValue = PyString_FromString(pickle);
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return NULL ;
}
// Set the argument into the pArgs tuple
PyTuple_SetItem(pArgs, 0, pValue);
// Run the python unpickle() function, get result pValue
pValue = PyObject_CallObject(pFunc, pArgs) ;
Py_DECREF(pArgs) ;
// Convert the Python string pValue to a C string
if (pValue != NULL) {
unpickledString = PyString_AsString(pValue) ;
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return NULL ;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find 'unpickle' function\n") ;
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load python script file\n");
}
Py_Finalize() ;
return unpickledString ;
}
More information about the capi-sig
mailing list