1

I have a C++ class that is exposed to python with boost python framework.

    struct Var
    {
        Var(std::string name) : name(name), value() {}
        std::string const name;
        float value;
    };

    BOOST_PYTHON_MODULE(hello)
    {
      class_<Var>("Var", init<std::string>())
        .def_readonly("name", &Var::name)
        .def_readwrite("value", &Var::value);
       ;
    }

Below is the python script using this class:

x = hello.Var("hello")
def print_func():
    print(x.value)

Is it possible to access the object x inside C++ code and assign the value member variable a value in c++ that is printed when print_func() is executed in the python script ?

sbunny
  • 433
  • 6
  • 25
  • Sure, any function in C++ that operates on an instance of `Var` can change its value as normal. e.g. `void setValue(Var& v, float value) { v.value = value; }`. You can then expose that function to python and call it to set `x.value`. Of course, since you defined `value` as a `readwrite` member, you can also just manipulate `x.value` directly in python. – 0x5453 May 21 '18 at 20:25
  • Can it be possible to get `x` as python object using `attr()` function, assign a value to `value` member variable and then somehow push the updated object back to the python script ? – sbunny May 21 '18 at 20:38
  • I think it's possible; you should be able to do something like `void setValue(boost::python::object& obj, float value) { obj.attr("value") = value; }` and then expose `setValue` to python. Though I'm not sure why you would want to do this. – 0x5453 May 21 '18 at 20:44
  • In the actual use case the member variable is a pointer to a class object that gets instantiated in the c++ code, this class is not exposed to python. – sbunny May 21 '18 at 22:39

1 Answers1

1

You can change your python and c++ code, as below

//I hope you are expecting some functionality like below

class Var
{
    public:
        Var(std::string name) : name(name), value() {}
        std::string const name;
        double value;
        void set_value();
        double get_value();
};

Var::set_value(double value)
{
    this->value = value;
}

double Var::get_value(){

    return this->value;
}

// c++ Var class constructor caller 
Var* var_constructor_caller(string name){

    return new Var(name);
}

BOOST_PYTHON_MODULE(hello_ext)
{
    //class_<Var>("Var", init<std::string>())
    class_<Valr>("Var") // this line is for c++ class not exposed to python
        .def("set_value", &Var::set_value)
        .def("get_value", &Var::get_value)
        .def_readonly("name", &Var::name)
        .def_readwrite("value", &Var::value);
    ;

    def("var_constructor_caller", var_constructor_caller, return_value_policy<manage_new_object>());
    // by <manage_new_object> return type you are giving owner ship to python to delete the object
}

Below is the python script using this class:

import hello_ext as hello
    var_obj = hello.var_constructor_caller("myname")
    var_obj.set_value(3.14)
    value = var_obj.get_value()
    print value 
    var_object.value = 5.75 #you call directly assign value also to c++ class data member 
    print value
HarshGiri
  • 408
  • 2
  • 12
  • Very close - in my case I needed just ```get_value()``` (```set.value``` is not required), with ```return value``` (not ```this->```, as it will look for "value" inside of python, not c++). However in general, you're right it is working. – Karls Jan 20 '20 at 14:34