[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