|
Boost : |
From: Ullrich Koethe (koethe_at_[hidden])
Date: 2000-12-11 12:39:16
John Barnard wrote:
>
> Before I ask my question about BPL, let me thank David, Ullrich, and
> all of the contributors and testers of BPL. I've been very impressed
> with it in the short time of being using it.
Thanks a lot.
> Now on to my question/problem: I'm trying to pass an Python subclass
> instance of a C++ abstract class back to C++. I have a Python class
> testPI which is a subclass of the wrapped C++ abstract class LogPI. I
> wish to pass an instance of testPI to a method draw of the wrapped C++
> class StochasticGrid (all of this in Python, of course), where the
> method draw expects a reference to a LogPI object. When I attempt to
> this I get the error message:
>
> RuntimeError: __init__ function for extension class 'LogPI' was never
> called.
>
> indicating the BPL was expecting a constructor for the abstract class
> LogPI. Can you do this in BPL or have I made an error. I've attached
> the relevant C++ and Python code below. I'm using Microsoft VC++ with
> the latest patches on MS 98SE.
>
I think you simply must wrap a constructor for 'LogPI' that can be
called from within Python. This works because BPL will actually
instantiate a 'LogPI_callback' which must not be an abstract class and
thus can be instantiated. (Note that in your example code,
'LogPI_callback' lacked a constructor. Note also that this constructor
must be called from within the Python-constructor - not doing this
caused the error message in your code.) Here is a simple example that
works for me:
#include "boost/python/class_builder.hpp"
#include <string>
struct Abstract
{
virtual std::string test() = 0;
};
struct Abstract_callback: Abstract
{
Abstract_callback(PyObject * self)
: m_self(self)
{}
std::string test()
{
return
boost::python::callback<std::string>::call_method(m_self, "test");
}
PyObject * m_self;
};
extern "C" void initabstract()
{
boost::python::module_builder a("abstract");
boost::python::class_builder<Abstract, Abstract_callback>
a_class(a, "Abstract");
a_class.def(boost::python::constructor<>()); // wrap a
constructor
a_class.def(&Abstract::test, "test");
}
Then in Python
>>> from abstract import *
>>> class A(Abstract):
... def __init__(self, text):
... Abstract.__init__(self) # call the base class
constructor
... self.text = text
... def test(self): # implement abstract
function
... return self.text
...
>>> a = A("Hello")
>>> a.test()
'Hello'
>>>
Ulli
-- ________________________________________________________________ | | | Ullrich Koethe Universität Hamburg / University of Hamburg | | FB Informatik / Dept. of Computer Science | | AB Kognitive Systeme / Cognitive Systems Group | | | | Phone: +49 (0)40 42883-2573 Vogt-Koelln-Str. 30 | | Fax: +49 (0)40 42883-2572 D - 22527 Hamburg | | Email: u.koethe_at_[hidden] Germany | | koethe_at_[hidden] | | WWW: http://kogs-www.informatik.uni-hamburg.de/~koethe/ | |________________________________________________________________|
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk