[C++-sig] Raw constructor (i.e. combination of make_constructor and raw_function)

Hans Meine hans_meine at gmx.net
Mon Aug 22 14:20:26 CEST 2005


Hi again,

and thanks for your answer!

On Monday 22 August 2005 02:47, David Abrahams wrote:
> > I am trying to do something like
> >
> >     python::class_<MyVector>("PythonVector", python::no_init)
> >         .def("__init__", python::raw_function(&createVector, 1));
> >
> > But this gives the vector as first element of the args tuple to
> > createVector().
>
> What's wrong with that?

Err, I was always trying to wrap some kind of factory functions.
You mean I should write initialization functions instead of constructing ones?
Hmm, I tried that, but again have problems:

My first try was to have an initialization function like this:

void initVectorValue(const python::tuple &args, const python::dict &)
{
    MyVector &result((python::extract<MyVector &>(args[0])()));
    int size = python::len(args) - 1;
    result.resize(size);
    for(int i=0; i<size; ++i)
        result[i] = python::extract<double>(args[i + 1])();
}

and export that with

 .def("__init__", raw_function(&initVectorValue, 2))

However, that would not compile with either 1.31.0 or 1.32.0, I got errors 
like

| /software/boost-1.32.0/include/boost-1_32/boost/python/raw_function.hpp: In
|    member function `PyObject*
|    boost::python::detail::raw_dispatcher<F>::operator()(PyObject*, 
PyObject*)
|    [with F = void (*)(const boost::python::tuple&, const 
boost::python::dict&)]
|    ':
| /software/boost-1.32.0/include/boost-1_32/boost/python/object/py_function.hpp:92:   
instantiated from `PyObject* 
boost::python::objects::full_py_function_impl<Caller, Sig>::operator()
(PyObject*, PyObject*) [with Caller = 
boost::python::detail::raw_dispatcher<void (*)(const boost::python::tuple&, 
const boost::python::dict&)>, Sig = boost::mpl::vector1<PyObject*>]'
| /software/boost-1.32.0/include/boost-1_32/boost/mpl/if.hpp:67:   
instantiated from here
| /software/boost-1.32.0/include/boost-1_32/boost/python/raw_function.hpp:29: 
error: invalid
|    use of void expression

I tried changing the return type of my function to MyVector &, but then trying 
to construct PythonVector objects results in:

| TypeError: No registered converter was able to extract a C++ reference to
| type vigra::PythonVector<float> from this Python object of type PythonVector 

BTW: vigra::PythonVector<float> is MyVector above, which I exported to python 
simply with
    python::class_<MyVector>("PythonVector", python::no_init).def(...

I am currently compiling 1.33.0 in order not to blame myself in that respect.

Ideally, I'd like to wrap factory functions like the createVector() I 
originally posted.  Then, one would not need default constructible classes 
whose default constructed objects can be brought to the correct state.
(E.g. MyVector should be of fixed, but variable size that can be set in the 
constructor.)

For now, I would be happy with a C++ resize(), but I need a workaround for the 
raw_function constructor.  The real motivation is that I want to pickle my 
vector objects, and AFAICS I need the constructor for this.  So far, I just 
exported the beforementioned createVector() factor function as a module 
function to python and used that for creating my objects, but how should 
pickle know that?

Ciao, /  /
     /--/
    /  / ANS



More information about the Cplusplus-sig mailing list