[C++-sig] Custom smart pointer with same behaviour as shared_ptr

Francis Moreau francis_moreau at hotmail.com
Mon Apr 2 22:10:15 CEST 2007


Hi,

I am passing Python objects to C++ through a shared_ptr smart pointer and 
it's work well. However I need to have the same behaviour as shared_ptr but 
with my own version of smart pointer. I try to register and expose my custom 
smart pointer but I have this compilation error:

boost/python/pointee.hpp(28) : error C2039: 'element_type': is not a member 
of 'CountedObjPtr<T>'
        with
        [
            T=PyCallEngineState
        ]
        boost/python/pointee.hpp(38) : see reference to class template 
instantiation 'boost::python::detail::pointee_impl<false>::apply<T>' being 
compiled
        with
        [
            T=CountedObjPtr<PyCallEngineState>
        ]
        boost/python/register_ptr_to_python.hpp(17) : see reference to class 
template instantiation 'boost::python::pointee<T>' being compiled
        with
        [
            T=CountedObjPtr<PyCallEngineState>
        ]
        PythonModules.cpp(113) : see reference to function template 
instantiation 'void 
boost::python::register_ptr_to_python<CountedObjPtr<T>>(void)'being compiled
        with
        [
            T=PyCallEngineState
        ]


Here is the content of the from_python file for my smart pointer:

  template <class T>
  struct CountedObjPtr_from_python
  {
    CountedObjPtr_from_python()
    {
      converter::registry::insert(&convertible,
                                  &construct,
                                  type_id<CountedObjPtr<T> >());
    }

    static void* convertible(PyObject* p)
    {
      if (p == Py_None) {
        return p;
      }

      return converter::get_lvalue_from_python(
        p, python::converter::registered<T>::converters);
    }

    static void construct(PyObject* source,
                          python::converter::rvalue_from_python_stage1_data* 
data)
    {
      void* const storage =
        ((python::converter::rvalue_from_python_storage<CountedObjPtr<T> 
 >*)data)->storage.bytes;
      // Deal with the "None" case.
      if (data->convertible == source) {
        new (storage) CountedObjPtr<T>();
      } else {
        new (storage) CountedObjPtr<T>(static_cast<T*>(data->convertible));
      }

      data->convertible = storage;
    }
  };


And here is the code where I register the smart pointer:

namespace boost{ namespace python{

  template <class T>
  struct pointee< CountedObjPtr<const T> >
  {
    typedef T type;
  };

  template <class T>
  inline T* get_pointer(CountedObjPtr<const T> const& p)
  {
    return const_cast<T*>(p.get());
  }

}}

template <typename T>
void register_CountedObjPtr_conversions()
{
  boost::python::converter::registry::insert(
    &CountedObjPtr_from_python<T>::convertible,
    &CountedObjPtr_from_python<T>::construct,
    boost::python::type_id<CountedObjPtr<T> >());
}

BOOST_PYTHON_MODULE(CallEngineExtending)
{
  python::class_<PyCallEngineState, PyCallEngineState_Wrapped,
                 boost::noncopyable>("PyCallEngineState")
    ;

  //register_ptr_to_python<boost::shared_ptr<PyCallEngineState> >();

  python::register_ptr_to_python<CountedObjPtr<PyCallEngineState> >();
  register_CountedObjPtr_conversions<PyCallEngineState>();
}

Is anyone knows what is missing or wrong with this code? Also, I am not sure 
this code manages the ref counting properly since there is no call to 
borrowed or something like this?

Any help would be appreciated,
Francis






More information about the Cplusplus-sig mailing list