Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Create and Use Instance of a Python Object with boost::python

Suppose I have a Python class like so:

class MyPythonClass:
    def Func1(self, param):
        return
    def Func2(self, strParam):
        return strParam

If I want to embed the Python script that contains that class in my C++ code, create an instance of that object via my C++ code, and then call a member on that python object, how do I go about that?

I would think it would be something like this:

namespace python = boost::python;
python::object main = python::import("main");
python::object mainNamespace = main.attr("__dict__");
python::object script = python::exec_file(path_to_my_script, mainNamespace);
python::object foo = mainNamespace.attr("MyPythonClass")();
python::str func2return = foo.attr("Func2")("hola");
assert(func2return == "hola");

But the many variations of this code I have tried have not worked. What is the magic sauce I need to pour over my code to be able to do this?

like image 982
caps Avatar asked Feb 10 '17 03:02

caps


1 Answers

This is what ultimately worked for me.

namespace python = boost::python;
python::object main = python::import("main");
python::object mainNamespace = main.attr("__dict__");

//add the contents of the script to the global namespace
python::object script = python::exec_file(path_to_my_script, mainNamespace);

//add an instance of the object to the global namespace
python::exec("foo = MyPythonClass()", mainNamespace);
//create boost::python::object that refers to the created object
python::object foo = main.attr("foo");

//call Func2 on the python::object via attr
//then extract the result into a const char* and assign it to a std::string
//the last bit could be done on multiple lines with more intermediate variables if desired
const std::string func2return = python::extract<const char*>(foo.attr("Func2")("hola"));
assert(func2return == "hola");

Feel free to comment if there is a better way.

like image 105
caps Avatar answered Oct 24 '22 19:10

caps