[C++-sig] Re: call_method
Brett Calcott
brett.calcott at paradise.net.nz
Sun Nov 17 00:42:57 CET 2002
>
> No, that's my point: we can do it /no matter how the T is held/.
>
> First imagine using handle<> as the 'other shared ptr' . Then you
> can easily replace it with PyObject* :
>
> struct pyobject_deleter
> {
> pyobject_deleter(handle<> p): p_(p)
> {
> }
>
> void operator()(void const *)
> {
> p_.reset();
> }
> private:
> handle<> p_;
> };
>
> template <class T>
> shared_ptr<T> make_shared(PyObject* p)
> {
> extract<T*> x(p);
> if (x)
> {
> return shared_ptr<T> px(x(),
pyobject_deleter(handle<>(borrowed(p)))));
> }
> else
> {
> // conversion failed
> }
> }
>
>
Ok, make_shared() increments the PyObject refcount, and the pyobject deleter
decrements it. But I still don't get the full picture -- can I put this back
in the context of my project.
Assumption: I have a c++ library and I want to layer the python stuff on top
with minimal intrusion.
It looks like this:
class agent
{
public:
virtual void do_something()
{
cout << "in c++";
}
};
typedef shared_ptr<agent> agent_ptr;
typedef vector<agent_ptr> agents;
class engine
{
agents m_agents;
public:
void add_agent(agent_ptr const &a)
{
m_agents.push_back(a);
}
void do_stuff_with_agents()
{
for_each(m_agents.begin(), m_agents.end(),
mem_fun(agent::do_something));
}
};
Note that I am using shared_ptr here for my own purpose *unrelated* to
python implementation.
Now, what do I need to do to expose my C++ lib to python and make
agent::do_something overrideable in python code?
in python I want:
from xxxx import *
class py_agent(agent):
def do_something():
print 'in python'
e = engine()
e.add_agent(agent())
e.add_agent(py_agent())
e.do_stuff_with_agents()
It seems I have to touch the source code - so we are intruding on the c++
lib. Not the best, but unavoidable in this situation I think. The 'crazy
pointer' solution required inheriting agent from a base class and adding a
constructor with PyObject *. But we can easily use some #ifdef's to compile
a pythonized-or-not version of the library.
Now the solution that you are proposing requires a call to make_shared. I'm
not sure where this is happening. Does Boost.Python do it for me? Am I
required to call it whenever I need to access the elements in m_agents? I
can't see how the solution you have can work without causing me to change
significantly the underlying c++ lib. Maybe I just don't get it yet.
Cheers,
Brett
More information about the Cplusplus-sig
mailing list