changing argument value in a C++/Python code -


my problem follow: have c++ code can't modify want (not written me , under intellectual property constraints). have link python code through python main. use boost::python reflection. @ point in code, c++ function use python overloaded function of c++ function modify parameter. function works great when used inside python. when called c++ function, modification of parameter not taken account while in c++. model problem, wrote simplified version aimed @ isolating problem.

here c++ classes:

#include <iostream> using namespace std; #include <boost/ref.hpp>  //class aimed @ modeling c++ user's type should used in python class c { public:     double myc;     c(){}     ~c(){}      void setvalue(double val) {         myc = val;     }      double getvalue() {         return myc;     } };  /*     class derived in python     want sure that:     - void (g) , non void (f) functions reflected , extended in python     - function (h) local type (c) use python overloaded     function of c++ function (g) */  class { public:     a(){int a_x=0;}     virtual ~a(){}     virtual int f(int ivar){         ivar = 0;         return ivar;     }     virtual void g(c * myc){         c calledc;         cout << "i should not here" << endl;   //when b::setparam call g, should python g, not virtual function base class         calledc.setvalue(0.);         //return *myc;     }     c h(){                  //this function wont overloaded in python         c myc;         //myc.setvalue(0.);         this->g(&myc);      //we want myc modified, , python overloaded version of g used         cout << "value in c++: " << myc.getvalue() << endl; //we want verify if myc has been modified in c++         return myc;     } };  /*     class called main in python.     it's function setparam aimed @ ensuring python extension of c++ class supported */  class b { public:     b(a & a){         setparam(a);      }     b(){         int u;         u = 0;     }     virtual ~b(){}     void setparam(a & a){         a.h();              //here code should call h overloaded function of derived class of in python     } }; 

the boost::python wrapper:

#include <boost/python.hpp> #include <python.h> #include <object.h> #include "classa.h"  #include <boost/python/module.hpp> #include <boost/python/def.hpp> #include <boost/python/implicit.hpp> #include <iostream> using namespace std;  using namespace boost::python;  /*     wrapper used allow overload of virtual function */ struct wrapperclassa : a, boost::python::wrapper<a>{     int f(int ivar){         if(override f = this->get_override("f")){             return f(ivar);         }         else {             return a::f(ivar);         }     }     int default_f(int ivar){         return this->a::f(ivar);     }      void g(c * myc){         if(override g = this->get_override("g")){                     g(myc);         }         else {             a::g(myc);         }     }     void default_g(c * myc){         this->a::g(myc);     } };  /*     refection of necessary classes , functions python */ boost_python_module(mywrapper){     class_<wrapperclassa, boost::noncopyable>("a", init<>())     .def("f", &a::f, &wrapperclassa::default_f)     .def("g", &a::g, &wrapperclassa::default_g)     ;      class_<b, boost::noncopyable>("b", init<>())     .def("setparam", &b::setparam)     ;      class_<c>("c", init<>())     .def("setvalue", &c::setvalue)     .def("getvalue", &c::getvalue)     .def_readwrite("myc", &c::myc)     ; } 

the python code:

from math import * # c++ library mywrapper import *  """     extension of c++ class     apy should used when type argument called     g should able use c++ c type object , modify     constructor call g in order verify myc treated mutable within python """ class apy(a):     def __init__(self):         a.__init__(self)         n = 0         x = 0.         myc = c()         self.g(myc)         print("value after 1st call within python: " + repr(myc.getvalue()))      def f(self, n):         n = 5         return n      def g(self, myc):         x = 7.0         myc.setvalue(x)         print("value in python: " + repr(myc.getvalue()))  """     main     myb.setparam should able pass apy argument """ mya = apy() myb = b() myb.setparam(mya) 

when run code, print("value in python: " + repr(myc.getvalue())) print 7, cout << myc.getvalue() << endl print 0 while variable @ 7. thank help.

the problem here when convert c instance python in call g(myc), boost.python uses by-value converter rather shallow converter (i.e. copies c instance), though you've passed pointer.

this design: when pass c++ pointer python, boost.python ensure python code doesn't have worry other c++ code deleting while python layer still has access it, lead dangerous memory errors. way ensure copy object.

if you'd force boost.python pass myc object reference, use g(boost::python::ptr(myc)) (or g(boost::ref(*myc)) if know it's not null), aware dangerous; need make sure python implementation of g() doesn't try hold onto argument beyond lifetime.

you can find more information here:

http://www.boost.org/doc/libs/1_48_0/libs/python/doc/v2/callbacks.html

you can use boost::shared_ptr pass arguments python without copying in safe way:

boost python: how call c++ virtual function


Comments

Popular posts from this blog

django - How can I change user group without delete record -

java - Need to add SOAP security token -

java - EclipseLink JPA Object is not a known entity type -