Does anyone have any suggestions for dealing with these issues? Aaron Aaron Bentley wrote:
David Abrahams wrote:
Aaron Bentley <abentley@panoramicfeedback.com> writes:
Hi, I'm having a problem with dynamic casting on an object constructed using Python. It seems as though the type of an owned object is being lost.
I suggest you reduce your problem to the smallest possible example that illustrates it. The answer will probably become obvious to you, but if it doesn't, please post your example here.
Okay, here's some stripped down examples:
---foo.h--- class BaseClass { public: BaseClass() {} virtual ~BaseClass() {} };
---foo.cpp--- ... SubClass *subclass_cast(BaseClass *el) { return dynamic_cast<SubClass *>(el); } ---bar.h--- class SubClass: public BaseClass { public: SubClass(); }; SubClass *subclass_cast(BaseClass *el);
void test_subclass(SubClass &el); ---bar.cpp--- ... SubClass::SubClass() { } void test_subclass(SubClass &el) { ; } --wrapper.cpp-- ... BaseClass *return_base(SubClass *el) { return el; } ... BOOST_PYTHON_MODULE(_element) { class_<BaseClass, std::auto_ptr<BaseClass>, boost::noncopyable>( "BaseClass", no_init) ; class_<SubClass, std::auto_ptr<SubClass>, bases<BaseClass>, boost::noncopyable>("SubClass") ; def ("subclass_cast", subclass_cast, return_internal_reference<1>()); def ("test_subclass", test_subclass); def ("return_base", return_base, return_internal_reference<1>());
... } --- test.py --- import _element def run_test(test_func, converter, caster, subclass): print "Testing %s" % subclass.__name__ subcl = subclass() try: test_func(subcl) print "subcl can be passed to %s directly" % test_func.__name__ except Exception, e: print print e print "subcl cannot be passed to %s directly:" % test_func.__name__ try: test_func(converter(subcl)) print "subcl can be passed to %s when returned as a base class" % \ test_func.__name__ except Exception, e: print print e print "subcl cannot be passed to %s when returned as a base class" % \ test_func.__name__ try: assert caster((subcl)) is not None print "subcl can be dynamically cast from subclass" except Exception, e: print if len(str(e)) > 0: print e print e.__class__ print "subcl cannot be dynamically cast from subclass" try: assert caster(converter(subcl)) is not None print "subcl can be dynamically cast from base class" except Exception, e: print if len(str(e)) > 0: print e print e.__class__ print "subcl cannot be dynamically cast from base class" run_test(_element.test_subclass, _element.return_base, _element.subclass_cast, _element.SubClass)
Everything except wrapper.cpp is built as one shared library.
When I run test.py, I get this: Testing SubClass subcl can be passed to test_subclass directly
Python argument types in pflib._element.test_subclass(SubClass) did not match C++ signature: test_subclass(8SubClass {lvalue}) subcl cannot be passed to test_subclass when returned as a base class subcl can be dynamically cast from subclass subcl can be dynamically cast from base class
If I change the constructor for SubClass to an inline constructor, I get this: Testing SubClass subcl can be passed to test_subclass directly subcl can be passed to test_subclass when returned as a base class
exceptions.AssertionError subcl cannot be dynamically cast from subclass
exceptions.AssertionError subcl cannot be dynamically cast from base class
So it seems I can't do implicit dynamic casts (passing a base-class pointer to a function taking a subclass pointer) and explicit dynamic casts at the same time.
Aaron
-- Aaron Bentley Director of Technology Panometrics, Inc.