Boost logo

Boost :

From: daniel kottow (daniel.kottow_at_[hidden])
Date: 2001-11-26 11:29:47


hello all,
my code is running now and i wish to thank people who gave their comments
on my problem. curiosly enough, or maybe reflecting shortcomings in my
posing of the question, all three answers were very different. i will try
to give my own now (based more on the solution that works for me than on a
profound understanding, but this may occurr frequently to occasional users
who *just* want to port some code from c++ to python).
in short, the answer to my question is: call the python interpreter to give
you one.
in code (please refer to the earlier posting for more code):

/********** first we need some helpers to call/register a python func
***********/
/**** this function gives us a new object from the user-derived python
class **********/

PyObject* PyGAGenome::newPythonUserGenome() const {
  PyObject *arglist, *result;
  arglist = Py_BuildValue("()"); //python constructor takes no args
  result = PyEval_CallObject(pyFuncNewGenome, arglist);
  Py_DECREF(arglist);
  return result;
}

void PyGAGenome::registerNewGenome(PyObject *args)
{
  pyFuncNewGenome = args; /* Remember new callback */
}

/**************** now clone may be implemented like this
*********************/

GAGenome * PyGAGenome::clone(GAGenome::CloneMethod) const {

   cout << "PyGAGenome::clone()\n";

  PyObject *userGenome;
  userGenome = newPythonUserGenome();

  //use from_python to get a PyGAGenome *
  PyGAGenome *pg;
  pg = BOOST_PYTHON_CONVERSION::from_python(userGenome,
python::type<PyGAGenome*>());

  return (GAGenome *)pg;
}

/************** copy needs no change, since it doesnt create objects
**************/

in PYTHON we then have (here PyGAGenome is called simply Genome):

def newExampleGenome():
        return ExampleGenome()
        
class ExampleGenome(Genome):
        def __init__(self):
                self.width = 4
                self.lower = 0
                self.upper = 1
                self.step = 0.1
                Genome.__init__(self, self.width, self.lower, self.upper,
self.step)
                self.registerNewGenome(newExampleGenome)
        def objective(self):
                d = subtract(self.genes() , [0.1, 0.2, 0.3, 0.4])
                r = sum(multiply(d,d))
                return self.width - r

so, indeed, i didnt have to worry about the PyGAGenome_Callback wrapper
class.
one hairy thing, and this may also help phil with from_python() is the fact
that you have to "provide" the from_python method by defining the following
*before* calling from_python:

struct PyGAGenomeClass
  : python::class_builder<PyGAGenome, PyGAGenome_Callback>
{ PyGAGenomePythonClass(python::module_builder&); };

(i found this trick in comprehensive.hpp)

i hope this may help some lost souls like myself...

BTW,
i think boost:python is a great enhancement as far as i can reach it.
its just pretty hard to reach.

greetings.

-- 
Daniel Kottow                                    daniel.kottow_at_[hidden]
Security and Testing Technology                 
http://vision.fhg.de/~daniel
Production Technology Centre                     Pascalstr. 8 - 9
Fraunhofer-Institut IPK Berlin                   D - 10587 Berlin

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