brett.calcott at paradise.net.nz
Tue Nov 12 10:59:57 CET 2002
From: "David Abrahams" <dave at boost-consulting.com>
Sent: Monday, November 11, 2002 1:43 AM
> > Ok, I thought this looked weird too. But given I want:
> > 1) An agent which I can instantiate from python but the execution of
> > do_something happens in c++.
> > 2) An agent which inherits all of the c++ agents properties, but can
> > do_something in python.
> > ...then the above code seemed the way to do it. You can stick some
> > intermediary class in, but it is effectively empty. Hmm. I guess I
> > am blindly following the examples.
> No, you are not. You should never expose py_agent explicitly.
The problem is I wanted to expose agent and py_agent, both of which require
using agent as the first template parameter. So this means I must use an
intermediary class between the two - Right?
> > Should I do this?
> > class_<agent, bases<>, agent_ptr>("agent", init<>())
> > .def("do_something", &agent::do_something)
> No, you should never expose a virtual funtion you intend to override
> in Python that way. Take a look at how "default_f" is used in
> If you made agent::do_something pure virtual, you wouldn't need to
> expose it at all.
Ok, I need to RTFM.
<ponders>Hmmm. Why can't you do that? Mem fun pointers to virtual functions
are ok. Aren't you storing them somewhere...</ponders>
I think I would blunder less if I actually knew how this stuff worked. I
believe you are writing something about the internals - I look forward to
> >> The only things I can imagine doing in the library which might help
> >> you are:
> >> 1. Change the protocol for derived wrapper classes (e.g. py_agent) so
> >> that they accept an instance of class object which actually holds a
> >> Python weak reference to the Python object. That way it would be
> >> possible to report errors when the m_self object was destroyed,
> >> instead of gracelessly crashing. Existing user code, would have to
> >> change to accomodate this, of course. Another downside is that
> >> every such Python instance would acquire a WeakRefList upon
> >> creation, which could cost a fair amount of memory per instance.
> >> 2. Build a nicer smart pointer than handle<> which also manages the
> >> Python object. handle<agent> won't work, because agent is not a
> >> PyObject (there's no ob_refcnt to manage). So, imagine
> >> py_ptr<agent>, which, when dereferenced, returns an agent&, but
> >> which manages the reference count of the owning Python object. You
> >> could stick those in your vector and then you wouldn't need to use
> >> extract<> explicitly.
> > I was trying to think of a solution myself today. I thought of something
> > along the lines of 2. Can I help?. (Of course, it may be quicker if you
> > do it yourself, given my knowledge of the internals of Boost.Python.)
> I'm always interested in getting helpful patches. You don't need to
> know very much about internals to do this job, since most everything
> you need to do involves existing documented high-level components like
> I'll help out when you get to the stage of needing to supply
> Python<->C++ conversions for these pointers.
> One thing you might consider is deriving these things from
Ok, I have something that works. I don't think it resembles what you had in
mind as I don't use extract<> or python::object. This is just a 'proof of
concept' - I would like your feedback on what might be bad/wrong/silly about
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<> approach
documented for the smart_ptr example doesn't work with msvc.
2. I use a py_counted_base which is inherited by the class that is pointed
too. I keep the PyObject *self in this class and Py_INCREF it if the use
count of the intrusive_ptr goes above 1. (see the code)
3. I create a to_python converter that returns the PyObject *self out of the
base class so we get object identity back in python.
See the included code.
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 4176 bytes
Desc: not available
More information about the Cplusplus-sig