[C++-sig] call_method

Brett Calcott brett.calcott at paradise.net.nz
Sun Nov 10 06:33:39 CET 2002


From: "David Abrahams" <dave at boost-consulting.com>
>
> It has nothing to do with all that. The first thing I notice is that
> what you're doing makes no sense:
>
>    class_<agent, bases<>, agent_ptr>("agent", init<>())
>       .def("do_something", &agent::do_something)
>       ;
>
>    class_<agent, bases<>, py_agent_ptr, boost::noncopyable>
>       ("py_agent", init<>())
>       .def("do_something", &agent::do_something)
>       ;
>
> You can't wrap class "agent" two different ways. I probably ought to
> generate some kind of assertion for this, but life is short...

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. Should I do this?

    class_<agent, bases<>, agent_ptr>("agent", init<>())
       .def("do_something", &agent::do_something)
       ;

    class_<py_agent, bases<agent>, py_agent_ptr, boost::noncopyable>
       ("py_agent", init<>())
       ;

> 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 just
do it yourself, given my knowledge of the internals of Boost.Python.)

Cheers,
Brett








More information about the Cplusplus-sig mailing list