[C++-sig] Problem using the ptr() function

David Abrahams dave at boost-consulting.com
Tue Nov 8 15:53:37 CET 2005


Emmanuel Taurel <etaurel at cells.es> writes:

> As requested by Dave, I have reduced my example as far as I can.

Your example can still be reduced a *lot* further. You could start by
taking out all the use of std::cout.  I doubt you need a loop in
a_new_method.  Next time, please remove *all* unnecessary code and get
it down to the bare minimum required to exhibit the behavior you don't
expect.

Anyway, this time the problem is pretty straightforward.  Basically,
ptr(p) will only work when the type of *p has been exported with
class_.  In that case, Python ends up with an object of some Python
type corresponding to the C++ type of *p, containing a copy of p.

You are converting MyStrArray to and from a Python list instead of
wrapping it as a class.  There's no way that modifications to a
regular python list will be able to automatically affect *p.

In the past it has been requested that we support "write-back"
converters that let you convert, e.g., a MyStrArray to a Python list,
and then, when the call completes, convert the list back to a
MyStrArray.  We don't support that yet, but since you're actually
doing the call from Python to C++, it's easy for you to fake it:

    python::list send_msa_(send_msa); // convert to a Python list
    
	call_method<void>(dev_ptr->m_self.get(),"a_new_method", send_msa_);

    send_msa = extract<MyStrArray>(send_msa_);

BTW, something about

  class DeviceWrap : public Device, public wrapper<Device>
  {
  public:
      DeviceWrap(PyObject *self):Device(),m_self(borrowed(self)) {};
      DeviceWrap(PyObject *self, const string &na):Device(na),m_self(borrowed(self)) {};

      handle<> m_self;
  };

looks very wrong.  If you're using wrapper<...> there's almost never
cause for an initial self argument, and storing it in a handle<> is
almost guaranteed to result in a leak or a reference counting error.
I would unconditionally drop handle<>, and either try to make
wrapper<Device> work by itself, using get_override to get ahold of
a_new_method, or drop wrapper<Device> store a raw PyObject* in lieu of
handle<>, specializing has_back_reference for Device.  In this case
the latter approach might be better, by allowing you to get rid of the
artificial derived class and the dangerous downcast.
    
Good luck,
Dave

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com




More information about the Cplusplus-sig mailing list