[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