[C++-sig] call_method

David Abrahams dave at boost-consulting.com
Sun Nov 10 13:43:47 CET 2002


"Brett Calcott" <brett.calcott at paradise.net.nz> writes:

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

> 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
http://www.boost.org/libs/python/doc/tutorial/doc/class_virtual_functions.html.
If you made agent::do_something pure virtual, you wouldn't need to
expose it at all.

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

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

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
python::object...

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list