Boost logo

Boost :

From: dkottowk_at_[hidden]
Date: 2001-11-23 15:18:47


hi all.
i am having difficulties with handling the copy of python-boosted objects FROM c++:
consider the following definitons, belonging to a genetic algorithm (GA) library:

class PyGenome : public Genome {

public:

   PyGenome(int width);

  PyGenome( const PyGenome & data);

  virtual float objective();

  virtual void copy(const Genome &data);
  virtual Genome * clone(Genome::CloneMethod = CONTENTS) const;

  PyObject *genes();

};

/* we need a derived class to handle virtual funcs with boost... */
class PyGenome_Callback : public PyGenome {

public:
  PyGenome_Callback(PyObject* self_, int width);

  PyGenome_Callback(PyObject *self_, const PyGenome & data);

  virtual void copy(const Genome &data);
  virtual Genome * clone(Genome::CloneMethod = CONTENTS) const;

  float objective();
  static float default_objective( PyGenome& self_);

private:
  PyObject *self;
};

the goal here is to be able to override the objective function objective() in python.
by that way we get a general purpose GA for use in python.
it is in the nature of GA that it has to copy/clone the genomes.
this occurrs from inside the algorithm, that is, from c++ code.
i did follow the tutorial, step "Overridable Virtual Functions" when coding.

i provided copy/clone for PyGenome and defined the same in PyGenome_Callback as follows:

PyGenome_Callback::PyGenome_Callback(PyObject *self_, const PyGenome & data)
  : PyGenome(data), self(self_) {}

void pyGenome_Callback::copy(const Genome &data) {
  cout << "called ga_callback copy " << endl;
  PyGenome::copy(data);
  cout << "self " << self << " this " << this << endl;
  self = ((const PyGenome_Callback &)data).self; // unnecessary ??
}

GAGenome * PyGenome_Callback::clone(GAGenome::CloneMethod) const {
  cout << "called ga_callback clone " << endl;
  cout << "self " << self << " this " << this << endl;
  return new PyGenome_Callback(self, *this);
}

float PyGenome_Callback::objective() {
  return boost::python::callback<float>::call_method(self, "objective");
}

now, the copy/clone methods from PyGenome_Callback are used by the GA when copy/cloning as i could verify with the debug output.
actually i get many objects and each one has its own data.
but when the python objective fn is called, from inside the c++ code,
i always see the same data.
i verified this by calling the exposed method genes().
actually the debug gives always the same mem location for the python reference self,
although the this pointer obviously varies.
my question is, how do i get a copy of PyGenome_Callback,
which also is a copy of the python-side of the object ?

greetings, daniel.

PS: i read in your tutorial also that non-intrusiveness is *the* major goal for boost-python. i believe people (as me) also consider using boost-python for developing directly extensions for python.
actually, as i found out when trying to port this GA library, it might not make so much sense to have as many types in python as you usually get in c++. and you would also want to take advantage of python built-in types like lists, so hand-crafting makes a lot of sense to me, anyway.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk