1

I'm trying to exposed object in boost python, wrapped in a custom wrapped pointer.

The problem: If I put the pointer class declaration in a namespace the boost python code does not compile. If I put it outside a namespace all is well.

Example which works:

    // dummy smart MyPtr class
    template <typename T> class MyPtr {
    public:
        typedef T element_type;

        MyPtr(): px(0) {}
        MyPtr(T* p): px(p) {}

        // base operators
        T* operator->() { return px; }
        const T* operator->() const { return px; }
        T& operator*() { return *px; }
        const T& operator*() const { return *px; }

        // getters
        T* get() { return px; }
        const T* get() const { return px; }

    private:
        T* px;
    };



template <typename T> T* get_pointer(MyPtr<T> const& p) 
{
  return const_cast<T*>(p.get());
}


namespace boost 
{ 
namespace python 
{

  template <typename T> struct pointee<MyPtr<T> >   
  {
    typedef T type;
  };
}
}

.
.
.

BOOST_PYTHON_MODULE(CmiObjectsPython)
{
.
.
bp::scope classScope = class_<NS1::Class, boost::noncopyable, MyPtr<NS1::Class> >("className", no_init)
        .def("func", &NS1::Class::func);
.
.

}

Example which does not work:

namespace NS2
{
    // dummy smart MyPtr class
    template <typename T> class MyPtr {
    public:
        typedef T element_type;

        MyPtr(): px(0) {}
        MyPtr(T* p): px(p) {}

        // base operators
        T* operator->() { return px; }
        const T* operator->() const { return px; }
        T& operator*() { return *px; }
        const T& operator*() const { return *px; }

        // getters
        T* get() { return px; }
        const T* get() const { return px; }

    private:
        T* px;
    };
}


template <typename T> T* get_pointer(NS2::MyPtr<T> const& p) 
{
  return const_cast<T*>(p.get());
}


namespace boost 
{ 
namespace python 
{

  template <typename T> struct pointee<NS2::MyPtr<T> >   
  {
    typedef T type;
  };
}
}

.
.
.

BOOST_PYTHON_MODULE(CmiObjectsPython)
{
.
.
bp::scope classScope = class_<NS1::Class, boost::noncopyable, NS2::MyPtr<NS1::Class> >("className", no_init)
        .def("func", &NS1::Class::func);
.
.

}

If I add:

using namespace NS2;

This has no effect.

The errors I get surround the inexistence of get_pointer for the class: /usr/include/boost/python/object/make_ptr_instance.hpp:30: error: no matching function for call to 'get_pointer(const NS2::MyPtr&)' (template error redacted for readability - obviously there are 20 lines of trails until this line is achieved.

The boost code in the make_ptr_instance looks like:

template <class Ptr>
static inline PyTypeObject* get_class_object(Ptr const& x)
{
    return get_class_object_impl(get_pointer(x));
}

So there is no real reason for the code not to work as far as I understand, since get_pointer is defined, and is outside a namespace as boost python expects.

What am I missing here?

Thanks, Max.

2
  • Use either NS2 or NS22. Commented Apr 7, 2015 at 5:53
  • that was obviously a typo :-) I use ns2 always in the code. (I redacted the namespace names manually when copying the code here so I made a typo in the error, but the code uses the same namespace of course everywhere..) Commented Apr 7, 2015 at 6:24

1 Answer 1

3

Unfortunately, many features of boost python are poorly documented. As I see from your code you need to move

template <typename T> T* get_pointer(NS2::MyPtr<T> const& p) 
{
  return const_cast<T*>(p.get());
}

into the same namespace, that contains MyPtr definition. Something like this

namespace NS2 
{
    template <typename T> T* get_pointer(MyPtr<T> const& p) 
    {
        return const_cast<T*>(p.get());
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Seem logical now that I look at the boost code again, if they wanted to reference the global namespace that'd need to call ::get_pointer in their code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.