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 [email protected] http://mail.python.org/mailman/listinfo/cplusplus-sig
