The recommended way is to query into the namespace in which the entity object was created, then store a handle to the entity object as a boost::python::object. When interacting with Python objects from C++, it is best to use boost::python::object whenever possible, as it provides a high-level notation that acts much like a Python variable. Additionally, it provides the appropriate reference counting to manage the lifetime of the Python object. For example, storing a raw pointer (i.e. pointerToPythonObj* ) would not extend the life of the Python object; if the Python object was garbage collected from within the interpreter, then pointerToPythonObj would be a dangling pointer.
Here is an example demonstrating this:
Entity.py:
class Entity:
def action(self):
print "in Entity::action"
main.cpp:
#include <boost/python.hpp>
int main()
{
namespace python = boost::python;
try
{
Py_Initialize(); // Start interpreter.
// Create the __main__ module.
python::object main = python::import("__main__");
python::object main_namespace = main.attr("__dict__");
// Import Entity.py, and instantiate an Entity object in the
// global namespace. PyRun_SimpleString could also be used,
// as it will default to running within and creating
// __main__'s namespace.
exec(
"import Entity\n"
"entity = Entity.Entity()\n"
, main_namespace
);
// Obtain a handle to the entity object created from the previous
// exec.
python::object entity = main_namespace["entity"];
// Invoke the action method on the entity.
entity.attr("action")();
}
catch (const python::error_already_set&)
{
PyErr_Print();
}
}
Running the above program results in the following output:
in Entity::action
If Entity.py is failing to be imported, then it may require adding its containing directory to the PYTHONPATH environment variable.