[C++-sig] call_method
Brett Calcott
brett.calcott at paradise.net.nz
Thu Nov 7 12:01:09 CET 2002
Hi all,
Firstly, thanks for the funky library - Dave and others. I am looking
forward to making my development go a lot faster by scripting most of it and
leaving just the core in c++.
I somewhat overwhelmed by the sophistication of the methods involved to make
this thing work so elegantly - so I am grappling to understand how to make
it do what I want. (Likely that I should do what *it* wants..)
First up - a documentation bug (if you haven't already found it). I have the
download from boost.org - not CVS and I see this in call_method.html
// Callback class
class Base_callback : public Base
{
public:
Base_callback(PyObject* self) : m_self(self) {}
char const* class_name() const { return call_method(m_self,
"class_name"); }
^^^^^^^^^^^^^^
char const* Base_name() const { return Base::class_name(); }
private:
PyObject* const m_self;
};
That should be:
char const* class_name() const { return call_method<char const*>(m_self,
"class_name"); }
Right? That had me fooled for a bit.
Now the problem:
class agent
{
public:
virtual char const *do_something() const
{
return "something";
}
virtual ~agent() { }
};
typedef boost::shared_ptr<agent> agent_ptr;
typedef std::vector<agent_ptr> agents;
class engine
{
public:
void add_agent(const agent_ptr &a)
{
m_agents.push_back(a);
}
agents m_agents;
};
BOOST_PYTHON_MODULE(pyengine)
{
using namespace boost::python;
class_<agents>("agents")
.def("__iter__", iterator<agents>())
;
class_<agent, bases<>, agent_ptr>("agent", init<const char *>())
.def("name", &agent::name,
return_value_policy<copy_const_reference>())
.def("do_something", &agent::do_something)
;
class_<engine>("engine", init<>())
.def("add_agent", &engine::add_agent)
.add_property("agents"
, make_getter(&engine::m_agents, return_internal_reference<>()))
;
}
This works fine as it is for creating engines and putting agents into it.
What I want to do now is have the option of creating a derived agent
"py_agent" which uses call_method() to allow python to "do_something".
However, I want both of these types to be in able to be put into the vector
of agents in the engine. To get this to work I need something like this I
think:
class py_agent : public agent
{
public:
py_agent(PyObject* self = 0) : m_self(self) {}
char const *do_something() const { return call_method<char
const*>(m_self, "do_something"); }
PyObject* const m_self;
};
But to use class_ on it I need to create another shared_ptr for the
py_agent,
typedef boost::shared_ptr<py_agent> py_agent_ptr;
and then this:
class_<agent, bases<>, py_agent_ptr, boost::noncopyable>("py_agent")
.def("do_something", &py_agent::do_something)
;
But now, I can't add a py_agent using the python exported "add_agent"
function, as it is not the right type.
I am used to using shared_ptr in vectors for containing derived types - so,
as in this case, the engine can call "do_something" on all of them and they
can all "do their thing". How, if at all, can I get this happening here...
Cheers,
Brett
More information about the Cplusplus-sig
mailing list