I have the following shortened program that embeds Python (it's stripped of all error handling, etc for shortness). It creates Python function as a string (which is required for my problem at hand) and then tries to call it and get whatever it returned using __builtin__.eval
.
#include <Python.h>
#include <iostream>
int main() {
// Initialize Python
Py_Initialize();
// Import builtin to get an access to eval
PyObject *builtins = PyImport_ImportModule("__builtin__");
PyObject *eval = PyObject_GetAttrString(builtins, "eval");
// Create an argument tuple for the eval
PyObject * args = PyTuple_New(1);
PyObject * name = PyString_FromString("f(10)");
PyTuple_SetItem(args, 0, name);
// Create a function
PyRun_SimpleString("f = lambda x: x * 2 - 3");
// Try to get the result of the function execution by calling eval on it
PyObject * result = PyObject_CallObject(eval, args);
// Fail if the result is null pointer
assert(result != NULL);
// Destroy Python frame
Py_Finalize();
}
In other words, this program is analogous to the following Python program:
f = lambda x: x * 2 - 3
import __builtin__
print __builtin__.eval("f(10)")
The problem is: it works flawlessly in Python (returning 17). But in C++, PyObject_CallObject
returns NULL pointer and the program fails at assert, even though eval should clearly have returned the result of f(10). My question is why?
Thank you for your answer!
P.S. If you want to try to compile that yourself, use the following command on Unix systems (I am using it on Ubuntu):
g++ -I/usr/include/python2.7 progname.cpp -lpython2.7 -g