Get a c++ pointer to a Python instance using Boost::Python
Question: I am working on embedding Python inside of a C++ application. When I create a
new object in Python, I want to be able to store a reference to that Object in
my C++ application, so that I can later call methods on that object. What's
the recommended way of doing this?

For Example, I would like to be able to do something like this :

**Entity.py**

    
    
    class Entity:
        def getPointer(self)
            return pointertoSelf;
    

**Manager.cpp**

    
    
    Py_Initialize();
    PyRun_SimpleString("import Entity");
    PyRun_SimpleString("entity = Entity.Entity()");
    
    pointerToPythonObj* = somehowGetPointerToObj("entity");
    


Answer: 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`](http://www.boost.org/doc/libs/1_59_0/libs/python/doc/v2/object.html#object-
spec). 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](http://coliru.stacked-
crooked.com/a/47ce432dd68e28be) 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`](http://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH)
environment variable.

