Dear Boost::python experts, I am trying to use a custom shared pointer type instead of boost::shared_pointer, in my case Teuchos::RCP from the Trilinos project. The details of Teuchos::RCP should not matter much here. In any case there is a Doxygen documentation on the Trilinos webpage.
For completeness I attached a simple example code, but let me explain here the problem. I have two simple classes A and B, where B is derived from A. The C++-functions: void computeOnA(Teuchos::RCP<A> a) { a->a *= 2; } and void computeOnAs(boost::shared_ptr<A> a) { a->a *= 2; } both work nicely from python. The function void computeOnTupleOfAs(const tuple& as) { for(int i = 0; i < len(as); ++i) { boost::shared_ptr<A> a = extract<boost::shared_ptr<A> >(as[i]); computeOnAs(a); } } also works nicely, given both tuples containing instances of A or the derived class B as expected. However the function: void computeOnTupleOfA(const tuple& as) { for(int i = 0; i < len(as); ++i) { Teuchos::RCP<A> a = extract<Teuchos::RCP<A> >(as[i]); computeOnA(a); } } only works given tuples of A and not the derived class B, the following error is shown: TypeError: No registered converter was able to produce a C++ rvalue of type Teuchos::RCP<A> from this Python object of type B. So my question is, which magic do I need to do (I am willing to use certain internals of boost::python) so that B elements can be extracted from tuples of Bs. I currently only provide the functions: T* get_pointer(Teuchos::RCP<T> const& p) T* get_pointer(Teuchos::RCP<T>& p) Thanks for any help, Holger
#include <boost/python.hpp> #include "iostream" #include "string" #include "util/verboseObject.h" #include <Teuchos_RCP.hpp> #include <Teuchos_RCPBoostSharedPtrConversions.hpp> #include "python/teuchosRCPPy.h" using namespace boost::python; using namespace std; using namespace parfem; using Teuchos::RCP; // the details about "VerboseObject" are not important here // VerboseObject is exported to python and provides a __str__ method. class A : public virtual VerboseObject { public: /** * \defgroup implement methods of VerboseObject */ /**@{*/ virtual std::ostream& describe(std::ostream& o, VerbLevel verb) const { o << "I am class A with a=" << a; return o; } /**@}*/ public: int a; }; class B : public A { public: /** * \defgroup implement methods of VerboseObject */ /**@{*/ virtual std::ostream& describe(std::ostream& o, VerbLevel verb) const { o << "I am class B with a=" << a << " and b=" << b; return o; } /**@}*/ public: int b; }; void computeOnA(Teuchos::RCP<A> a) { a->a *= 2; } void computeOnTupleOfA(const tuple& as) { for(int i = 0; i < len(as); ++i) { Teuchos::RCP<A> a = extract<Teuchos::RCP<A> >(as[i]); computeOnA(a); } } void computeOnAs(boost::shared_ptr<A> a) { a->a *= 2; } void computeOnTupleOfAs(const tuple& as) { for(int i = 0; i < len(as); ++i) { boost::shared_ptr<A> a = extract<boost::shared_ptr<A> >(as[i]); computeOnAs(a); } } BOOST_PYTHON_MODULE(rcpPy) { class_<A, Teuchos::RCP<A>, bases<VerboseObject> >("A", init<>()) .def_readwrite("a", &A::a) ; class_<B, Teuchos::RCP<B>, bases<A> >("B", init<>()) .def_readwrite("b", &B::b) ; def("computeOnA", &computeOnA); def("computeOnTupleOfA", &computeOnTupleOfA); class_<A, boost::shared_ptr<A>, bases<VerboseObject> >("As", init<>()) .def_readwrite("a", &A::a) ; class_<B, boost::shared_ptr<B>, bases<A> >("Bs", init<>()) .def_readwrite("b", &B::b) ; def("computeOnAs", &computeOnAs); def("computeOnTupleOfAs", &computeOnTupleOfAs); } // boost module
#pragma once #include <Teuchos_RCP.hpp> template<class T> T* get_pointer(Teuchos::RCP<T> const& p) { return p.get(); } template<class T> T* get_pointer(Teuchos::RCP<T>& p) { return p.get(); }
test_rcp.py.out
Description: Binary data
from parfem import * print "######## test with boost::shared_ptr:\n\n" a = As(); b = Bs(); a.a = 1; b.a = 2; b.b = 3; print 'a:', a computeOnAs(a) print 'after computeOnA(a):', a computeOnTupleOfAs( (a, ) ) print 'after computeOnTupleOfAs( (a, ) ):', a print 'b:', b computeOnAs(a) print 'after computeOnA(b):', b computeOnTupleOfAs( (b, ) ) print 'after computeOnTupleOfAs( (b, ) ):', b print "######## test with Teuchos::RCP:\n\n" a = A(); b = B(); a.a = 1; b.a = 2; b.b = 3; print 'a:', a computeOnA(a) print 'after computeOnA(a):', a computeOnTupleOfA( (a, ) ) print 'after computeOnTupleOfA( (a, ) ):', a print 'b:', b computeOnA(a) print 'after computeOnA(b):', b computeOnTupleOfA( (b, ) ) print 'after computeOnTupleOfA( (b, ) ):', b
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig