[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