[C++-sig] Less than transparent proxies

Raoul Gough RaoulGough at yahoo.co.uk
Sat Apr 12 11:47:00 CEST 2003


I have a situation where I want to expose a C++ proxy class to Python,
and have access to features of the original object *and* the proxy
object. As a very simple example of this, boost::shared_ptr provides a
member function unique(). However, using shared_ptr as a holder (or
proxy) for your own type T leaves the features of the shared_ptr
object invisible to Python, and so the unique() function is
inaccessible.

I've thought of various ways of trying to work the proxies into
Python. Obviously Python doesn't have an indirection operator->(),
which is how this is often done in C++ (i.e. client code has to know
about the proxy object, and uses operator->() when accessing features
of the referant). One option might be to try and set up some kind of
IS-A relationship between the Python types (referant IS-A proxy), but
I'm starting to think the cleanest option would be to provide a
__cxxholder__ method so that client code can explicitly access the
holder/proxy when necessary.

e.g.

obj = HeldViaProxyType()
if obj.__cxxholder__().unique():
    # ...

Unfortunately, I seem to have hit a serious problem right away. The
test code (below) produces "already has a registered
to_python_converter" at load time, when defining the shared_ptr class
which is already registered as a holder for the referant. I guess this
was inevitable. Any suggestions or interest in the idea?

--
Raoul Gough
see http://home.clara.net/raoulgough/ for my work availability

----8<---- code starts ----8<----

#include <iostream>
#include <ostream>
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>

struct Hello {
  Hello () {
    std::cout << "Hello::Hello\n";
  }

  ~Hello () {
    std::cout << "Hello::~Hello\n";
  }

  void hello () { std::cout << "hello\n"; }
};

BOOST_PYTHON_MODULE (proxy)
{
  using namespace boost::python;

  try
    {
      class_<Hello, boost::shared_ptr<Hello> >
        hello_class ("Hello");

      hello_class.def ("hello", &Hello::hello);

      class_<boost::shared_ptr<Hello> >
        ptr_class ("HelloPtr");

      ptr_class.def ("unique", &boost::shared_ptr<Hello>::unique);
    }

  catch(...)
    {
      handle_exception();
    }
}

----8<---- example error ----8<----

$ python
Python 2.2.2 (#37, Oct 14 2002, 17:02:34) [MSC 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import proxy
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: trying to register to_python_converter for a type which
already has a registered to_python_converter
>>> ^Z







More information about the Cplusplus-sig mailing list