[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
   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(); }
   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
   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

   void add_agent(const agent_ptr &a)

   agents m_agents;

   using namespace boost::python;

      .def("__iter__", iterator<agents>())

   class_<agent, bases<>, agent_ptr>("agent", init<const char *>())
      .def("name", &agent::name,
      .def("do_something", &agent::do_something)

   class_<engine>("engine", init<>())
      .def("add_agent", &engine::add_agent)
        , 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

class py_agent : public agent
   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

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...


More information about the Cplusplus-sig mailing list