[C++-sig] problems downcasting intrusive_ptr.
Lucio Moser
lucio at image-engine.com
Sat Feb 10 01:45:05 CET 2007
Hello,
I created a factory function that returns an intrusive pointer for a
derived class.
The returned pointer is for the base class, but boost.python apparently
downcast it correctly.
I can call methods from the derived class with no problem.
But then, if I pass that object to any function that requires a derived
pointer it will fail.
If I use shared_ptr instead. It works fine.
Any ideas?
Thank you!
PS: I'm using boost 1.33.1.
python test case:
============
Object b can't be given as a parameter for test2() function!!!
Python 2.5 (r25:51908, Nov 17 2006, 14:19:39)
[GCC 4.0.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from simpleTest import *
>>> a = Derived()
>>> b = factory()
>>> b
<simpleTest.Derived object at 0xb7e87d84>
>>> a.test1()
0
>>> b.test1()
0
>>> a.test2(a)
1
>>> b.test2(a)
1
>>> b.test2(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Derived.test2(Derived, Derived)
did not match C++ signature:
test2(Derived {lvalue}, boost::intrusive_ptr<Derived>)
>>> a.test2(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Derived.test2(Derived, Derived)
did not match C++ signature:
test2(Derived {lvalue}, boost::intrusive_ptr<Derived>)
>>>
simpleTest.cpp:
===========
#include <boost/python.hpp>
class Base
{
public :
Base ( ) : m_numRefs( 0 )
{
}
// Functions used for intrusive_ptr reference counting.
/// Add a reference to the current object
void addRef() const {
m_numRefs ++;
}
/// Remove a reference from the current object
void removeRef() const {
m_numRefs --;
if ( m_numRefs == 0 )
{
delete this;
}
}
protected :
mutable unsigned int m_numRefs;
virtual ~Base()
{
}
};
class Derived;
#ifdef USE_SHARED_PTR
#include "boost/shared_ptr.hpp"
typedef boost::shared_ptr<Base> BasePtr;
typedef boost::shared_ptr<Derived> DerivedPtr;
#else // USE_SHARED_PTR
#include "boost/intrusive_ptr.hpp"
typedef boost::intrusive_ptr<Base> BasePtr;
typedef boost::intrusive_ptr<Derived> DerivedPtr;
/// Functions required to allow use of Base with boost::intrusive_ptr
inline void intrusive_ptr_add_ref( const Base *r )
{
r->addRef();
}
inline void intrusive_ptr_release( const Base *r )
{
r->removeRef();
}
#endif // USE_SHARED_PTR
class Derived : public Base
{
public :
Derived( ) : Base ( ), m_data( 0 )
{
}
int test1()
{
return this->m_data;
}
int test2( DerivedPtr d )
{
return (this->m_data == d->m_data);
}
protected :
int m_data;
};
BasePtr factory( void )
{
return BasePtr( new Derived() );
}
using namespace boost::python;
BOOST_PYTHON_MODULE(simpleTest)
{
class_< Base, boost::noncopyable, BasePtr > BaseClass("Base", no_init);
class_< Derived, boost::noncopyable, DerivedPtr, bases< Base > >
DerivedClass( "Derived" );
DerivedClass.def( "test1", &Derived::test1 );
DerivedClass.def( "test2", &Derived::test2 );
def("factory", &factory);
implicitly_convertible<DerivedPtr, BasePtr>();
}
More information about the Cplusplus-sig
mailing list