[C++-sig] call_method

Brett Calcott brett.calcott at paradise.net.nz
Wed Nov 13 10:07:23 CET 2002

> > The problem is I wanted to expose agent and py_agent,
> Why?

Here is some context:
I am writing a multi-agent simulation. I have done a bit of this in C++, but
this time I want to write just the core engine in C++ and use python for all
the surrounding framework. I want to be able to create agents, save them,
query them, all using a commandline or gui in python (wx probably). However,
when it comes to the actual simulation I want this to happen in C++. It's a
bit like Numeric - the workhorse calls involving iteration across lots of
data happen in C. However, for experimental purposes, I want to be able
create a python agent which inherits all of the features of the normal
agent - but allows me to override certain things. Once I get something
right, I can push the python code back into C++ for speed.

So - I wanted agent to be exposed to python so I can create pure C++ agents,
and py_agent exposed so I can choose to override the default compiled
behaviour and sacrifice some speed whilst I mess around with new features.

Actually (although it no longer matters with the solution I have no using
to_python converters) I needed to expose agent otherwise the the python
calls involving agent_ptr would not work.

> >
> > The outline is this:
> > 1. I use the intrusive_ptr template in boost. This is currently
> > undocumented, and I also needed to add a 'typedef T element_type' to the
> > class to make it work with Boost.Python. Note that the pointee<>
> > documented for the smart_ptr example doesn't work with msvc.
> Of course not ;-)

I tried it first before I realised (Duh). Probably worth mentioning in the

> Well, I think it's damned cool! I spent a bunch of time turning
> approaches like this one over and over in my mind, but I couldn't see
> how to make it work. At first I thought your design had to be broken,
> but I failed to poke any holes in it. IIUC, the structure looks like
> this:

Yeah, I thought it had to be broken too at first :)

>       PyObject
>     +-----------+
>     | ob_refcnt |       py_agent
>     +-----------+       +------------+
>     | agent_ptr |------>| use_count_ |
>     +-----------+       +------------+
>         ^               |     pyobj_ |--+
>         |               +------------+  |
>         |               |     ...    |  |
>         |               +------------+  |
>         |                               |
>         +-------------------------------+

Nice picture!

> Your remarks here:
>     // need to put them in the boost namespace so they get found
>     // before the defaults
>     namespace boost
>     {
>        inline void intrusive_ptr_add_ref(py_counted_base * p)
>        {
>           p->add_ref();
>        }
>        inline void intrusive_ptr_release(py_counted_base * p)
>        {
>           p->release();
>        }
>     } // end namespace boost
> Are wrong, and putting these in namespace boost will not work on
> conforming compilers. They need to go in the same namespace as
> py_counted_base on most compilers. For compilers that don't do Koenig
> lookup namespace boost will probably be OK.

Koenig lookup. Sigh... You forget about that sort of thing after using the
same broken compiler for 4 years. 'Whatever works' becomes your motto.

> I'd like to explore a few refinements with you. For example, it may be
> possible to get real shared_ptr interoperability by deriving
> py_counted_base from counted_base. Maybe we should ask Peter to weigh
> in on this. Peter, Brett's code is attached to this page:
> http://aspn.activestate.com/ASPN/Mail/Message/1430235

Ok. I'm enjoying this.


More information about the Cplusplus-sig mailing list