[C++-sig] exporting const array members
Gary Oberbrunner
garyo at genarts.com
Fri Oct 18 16:14:48 CEST 2013
Hi folks; I hope someone can help with a problem I'm having.
I have Base and Other classes (sorry for the generic names), and Base contains a fixed-length const array of pointers to Others. I'm trying to expose Base to python. I started with a pyplusplus run and hand-massaged the result, so it uses the autogenerated __array_1.pypp.hpp. I've included my entire code, including my classes and the boost.python wrappers.
The problem is that boost.python fails to wrap the "others" member variable of Base; it ends up trying to cast an Other *const to an Other *. At the end, I'll include the whole error message. It seems like it doesn't propagate the constness through pytype_function, but I don't know enough boost to be sure of that. (This is on Windows 7, MSVC 10, boost 1.54.)
(I can't change the structure of the Base or Other classes much; they're from a larger system.)
Thanks in advance!
Code:
=====================
// Classes to expose
struct Other {
int dummy;
};
struct Base {
struct Other * const others[49];
Base() : others() { };
};
// Boost.Python stuff
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/return_value_policy.hpp>
#include <boost/python/manage_new_object.hpp>
#include "__array_1.pypp.hpp"
namespace bp = boost::python;
struct Base_wrapper : Base, bp::wrapper< Base > {
Base_wrapper(Base const & arg )
: Base( arg )
, bp::wrapper< Base >(){
// copy constructor
}
Base_wrapper()
: Base()
, bp::wrapper< Base >(){
// null constructor
}
static pyplusplus::containers::static_sized::const_array_1_t< ::Other * const, 49>
pyplusplus_others_wrapper( ::Base & inst ){
return pyplusplus::containers::static_sized::const_array_1_t< ::Other * const, 49>( inst.others );
}
};
BOOST_PYTHON_MODULE(foo)
{
using namespace bp;
{ //::Base
typedef bp::class_< Base_wrapper > Base_exposer_t;
Base_exposer_t Base_exposer = Base_exposer_t( "Base" );
bp::scope Base_scope( Base_exposer );
pyplusplus::containers::static_sized::register_const_array_1< ::Other * const, 49, bp::return_internal_reference< > >( "__array_1__scope_other_const__ptr__49" );
{ //Base::others [variable], type=Other * const[49]
typedef pyplusplus::containers::static_sized::const_array_1_t< ::Other * const, 49> ( *array_wrapper_creator )( ::Base & );
Base_exposer.add_property( "others"
, bp::make_function( array_wrapper_creator(&Base_wrapper::pyplusplus_others_wrapper)
, bp::with_custodian_and_ward_postcall< 0, 1 >() ) );
}
}
}
=====================
Error message:
=====================
foo.cxx(11) : warning C4351: new behavior: elements of array 'Base::others' will be default initialized
C:\boost\include\boost-1_54\boost/python/detail/unwind_type.hpp(165) : error C2664: 'boost::python::converter::detail::unwind_type_id_helper::result_type boost::python::detail::unwind_helper2<1>::execute<Generator,Other>(U *(__cdecl *)(void),Generator *)' : cannot convert parameter 1 from 'Other *const (__cdecl *)(void)' to 'Other *(__cdecl *)(void)'
with
[
Generator=boost::python::converter::detail::unwind_type_id_helper,
U=Other
]
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
C:\boost\include\boost-1_54\boost/python/converter/pytype_function.hpp(45) : see reference to function template instantiation 'boost::python::converter::detail::unwind_type_id_helper::result_type boost::python::detail::unwind_type<boost::python::converter::detail::unwind_type_id_helper,T>(boost::type<T> *,Generator *)' being compiled
with
[
T=Other *const ,
Generator=boost::python::converter::detail::unwind_type_id_helper
]
C:\boost\include\boost-1_54\boost/python/converter/pytype_function.hpp(67) : see reference to function template instantiation 'boost::python::type_info boost::python::converter::detail::unwind_type_id_<T>(boost::type<T> *,boost::mpl::false_ *)' being compiled
with
[
T=Other *const
]
C:\boost\include\boost-1_54\boost/python/converter/pytype_function.hpp(65) : while compiling class template member function 'const PyTypeObject *boost::python::converter::expected_pytype_for_arg<T>::get_pytype(void)'
with
[
T=Other *const
]
C:\boost\include\boost-1_54\boost/preprocessor/iteration/detail/local.hpp(34) : see reference to class template instantiation 'boost::python::converter::expected_pytype_for_arg<T>' being compiled
with
[
T=Other *const
]
C:\boost\include\boost-1_54\boost/python/detail/signature.hpp(76) : while compiling class template member function 'const boost::python::detail::signature_element *boost::python::detail::signature_arity<2>::impl<Sig>::elements(void)'
with
[
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/detail/signature.hpp(58) : see reference to class template instantiation 'boost::python::detail::signature_arity<2>::impl<Sig>' being compiled
with
[
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/detail/caller.hpp(232) : see reference to class template instantiation 'boost::python::detail::signature<Sig>' being compiled
with
[
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/detail/caller.hpp(231) : while compiling class template member function 'boost::python::detail::py_func_sig_info boost::python::detail::caller_arity<2>::impl<F,Policies,Sig>::signature(void)'
with
[
F=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
Policies=boost::python::return_internal_reference<>,
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/detail/caller.hpp(169) : see reference to class template instantiation 'boost::python::detail::caller_arity<2>::impl<F,Policies,Sig>' being compiled
with
[
F=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
Policies=boost::python::return_internal_reference<>,
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/make_function.hpp(61) : see reference to class template instantiation 'boost::python::detail::caller<F,CallPolicies,Sig>' being compiled
with
[
F=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
CallPolicies=boost::python::return_internal_reference<>,
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/make_function.hpp(146) : see reference to function template instantiation 'boost::python::api::object boost::python::detail::make_function_aux<F,CallPolicies,Signature,boost::mpl::int_<N>>(F,const CallPolicies &,const Sig &,const boost::python::detail::keyword_range &,NumKeywords)' being compiled
with
[
F=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
CallPolicies=boost::python::return_internal_reference<>,
Signature=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>,
N=1,
Sig=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>,
NumKeywords=boost::mpl::int_<1>
]
C:\boost\include\boost-1_54\boost/python/class.hpp(545) : see reference to function template instantiation 'boost::python::api::object boost::python::make_function<Fn,T2,T1,boost::mpl::vector3<T0,pyplusplus::containers::static_sized::const_array_1_t<TItemType,size> &,unsigned long>>(F,const CallPolicies &,const Keywords &,const Signature &)' being compiled
with
[
Fn=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
T2=boost::python::return_internal_reference<>,
T1=boost::python::detail::keywords<1>,
T0=Other *const ,
TItemType=Other *const ,
size=49,
F=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
CallPolicies=boost::python::return_internal_reference<>,
Keywords=boost::python::detail::keywords<1>,
Signature=boost::mpl::vector3<Other *const ,pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49> &,unsigned long>
]
C:\boost\include\boost-1_54\boost/python/class.hpp(260) : see reference to function template instantiation 'void boost::python::class_<W>::def_impl<pyplusplus::containers::static_sized::const_array_1_t<TItemType,size>,Fn,boost::python::detail::def_helper<T1,T2>>(T *,const char *,Fn,const Helper &,...)' being compiled
with
[
W=wrapper_t,
TItemType=Other *const ,
size=49,
Fn=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
T1=boost::python::detail::keywords<1>,
T2=boost::python::return_internal_reference<>,
T=pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>,
Helper=boost::python::detail::def_helper<boost::python::detail::keywords<1>,boost::python::return_internal_reference<>>
]
c:\tmp\__array_1.pypp.hpp(143) : see reference to function template instantiation 'boost::python::class_<W> &boost::python::class_<W>::def<Other*const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<TItemType,size>::* )(unsigned long) const,boost::python::detail::keywords<1>,boost::python::return_internal_reference<>>(const char *,Fn,const A1 &,const A2 &)' being compiled
with
[
W=wrapper_t,
TItemType=Other *const ,
size=49,
Fn=Other *const (__thiscall pyplusplus::containers::static_sized::const_array_1_t<Other *const ,49>::* )(unsigned long) const,
A1=boost::python::detail::keywords<1>,
A2=boost::python::return_internal_reference<>
]
c:\tmp\__array_1.pypp.hpp(135) : while compiling class template member function 'pyplusplus::containers::static_sized::register_const_array_1<TItemType,size,CallPolicies>::register_const_array_1(const char *)'
with
[
TItemType=Other *const ,
size=49,
CallPolicies=boost::python::return_internal_reference<>
]
foo.cxx(59) : see reference to class template instantiation 'pyplusplus::containers::static_sized::register_const_array_1<TItemType,size,CallPolicies>' being compiled
with
[
TItemType=Other *const ,
size=49,
CallPolicies=boost::python::return_internal_reference<>
]
=====================
-- Gary
More information about the Cplusplus-sig
mailing list