How to do this
c++ -> Python -> c++
^ |
| |
-----------------
Example with code:
Imagine I have a C++ class wrapped for python (e.g. using boost.python)
// foo.cpp
#include <boost/python.hpp>
struct Cat {
Cat (int fur=4): _fur{i} { }
int get_fur() const { return _fur; }
private:
int _fur;
};
BOOST_PYTHON_MODULE(foo) {
using namespace boost::python;
class_<Cat>("Cat", init<int>())
.def("get_fur", &A::get_fur, "Density of cat's fur");
}
Now I'm hosting a python in C++. A python script creates Cat => A c++ Cat instance is created underneath. How to get a pointer to c++ instance of Cat from hosting c++ (from C++ to C++)?
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from cat import Cat \n"
"cat = Cat(10) \n");
// WHAT to do here to get pointer to C++ instance of Cat
... ??? ...
std::cout << "Cat's fur: " << cat->get_fur() << std::endl
Py_Finalize();
return 0;
}
Real application The real problem is this: we have a c++ framework which has pretty complex initialization and configuration phase where performance is not critical; and then processing phase, where performance is everything. There is a python wrapping for the framework. Defining things in python is very convenient but running from python is still slower than pure c++ code. It is tempting for many reasons to do this configuration/initialization phase in python, get pointers to underneath C++ objects and then run in "pure c++ mode". It would be easy if we could write everything from scratch, but we have already pretty much defined (30 years old) c++ framework.
#include <Python.h>
int main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]);
Py_Initialize();
object module = import("__main__");
object space = module.attr("__dict__");
exec("from cat import Cat \n"
"cat = Cat(10) \n",
space);
Cat& cat = extract<Cat&>(space["cat"]);
std::cout<<"Cat's fur: "<< cat.get_fur() <<"\n";
//or:
Cat& cat2 = extract<Cat&>(space.attr("cat"));
std::cout<<"Cat's fur: "<< cat2.get_fur() <<"\n";
//or:
object result = eval("cat = Cat(10)");
Cat& cat3 = extract<Cat&>(result);
std::cout<<"Cat's fur: "<< cat3.get_fur() <<"\n";
Py_Finalize();
return 0;
}