title: Boost.Python + OpenGL segmentation faults
body: <p>I have a (almost) perfectly working C++ code written with Boost.Python. It wraps a shared pointer based structure hierarchy of 3 or 4 classes, nothing terribly complex (i.e. class A has a std::vector of class B instance pointers, etc.), top level package called, say, foo.</p>
  
  <p>Some time ago I decided to add visualization to the project using PyOpenGL. So now, whenever I have <code>import OpenGL</code> before I have <code>import foo</code>, I'm getting segmentation faults inside C++ code (such as when I iterate over a sequence of objects and their child objects.)</p>
  
  <p>My best assumption is that OpenGL somehow substitutes memory allocation functions or does something similarly unholy. Any one can shed some light on the situation? I'll try to provide more details on request, but the whole thing seems to be rather chaotic.</p>
  
  <p>On request, isolated test case:</p>
  
  <p>Makefile:</p>
  
  <pre><code>all:
      g++ -shared -o foo.so -fPIC \
          -I/usr/include/boost-1_37/ -I/usr/include/python2.5 \
          -lpython2.5 -lboost_python-1_37 \
          foo.cpp
  </code></pre>
  
  <p>Python file:</p>
  
  <pre><code>from OpenGL import *
  import foo
  
  b = foo.B()
  
  for i in range(10):
      b.elements.append(foo.A())
  
  for e in b.elements:
      print e
  
  # Crash here if `from OpenGL import *` is present.
  </code></pre>
  
  <p>C++ file:</p>
  
  <pre><code>#include &lt;boost/python.hpp&gt;
  #include &lt;boost/shared_ptr.hpp&gt;
  #include &lt;vector&gt;
  
  namespace bp = boost::python;
  
  struct A {
      typedef boost::shared_ptr&lt;A&gt; ptr;
  };
  
  struct B {
      typedef boost::shared_ptr&lt;B&gt; ptr;
      std::vector&lt;A::ptr&gt; elements;
  };
  
  
  // Proxies B::elements without converting them 
  // back and forth between lists.
  struct ElementProxy {
  
      static ElementProxy 
      init(B::ptr b)
      {
          return ElementProxy(b);
      }
  
      ElementProxy(B::ptr b)
      : b_(b)
      {}
  
      size_t
      len() 
      {
          return (*b_).elements.size();
      }
  
      A::ptr
      getitem(size_t i) 
      {
          if (i &gt;= len()) {
              PyErr_SetString(PyExc_IndexError, "Index out of bounds.");
              bp::throw_error_already_set();
          }
          return (*b_).elements[i];
      }
  
      void
      append(A::ptr e) 
      {
          (*b_).elements.push_back(e);
      }
  
      static boost::python::class_&lt;ElementProxy&gt; 
      wrap() 
      {
          return bp::class_&lt;ElementProxy&gt;("ElementProxy", bp::no_init)
  
              .def("__len__", &amp;ElementProxy::len, 
                   (bp::arg("self")),
                   "Returns the number of contained elements"
                   )
  
              .def("__getitem__", &amp;ElementProxy::getitem, 
                   (bp::arg("self"), bp::arg("i")), 
                   "Returns the element at given index"
                   )
  
              .def("append", &amp;ElementProxy::append, 
                   (bp::arg("self"), bp::arg("element")), 
                   "Appends an element"
                   )
              ;
      }
  
  private:
  
      B::ptr b_;
  };
  
  
  
  BOOST_PYTHON_MODULE(foo) {
  
      bp::class_&lt;A, A::ptr, boost::noncopyable&gt;("A") ;
  
      ElementProxy::wrap();
  
      bp::class_&lt;B, B::ptr, boost::noncopyable&gt;("B")
          .add_property("elements", &amp;ElementProxy::init) ;
  }
  </code></pre>