2009-11-17 41 views
1

我有一個用Boost.Python編寫的(幾乎)完美工作的C++代碼。它包裝了3或4類的基於共享指針的結構層次結構,沒有什麼非常複雜的(即類A具有類B實例指針等的std :: vector),稱爲foo的頂層包。Boost.Python + OpenGL分段錯誤

前段時間我決定使用PyOpenGL爲項目添加可視化。所以現在,只要我有import OpenGL之前,我有import foo,我得到C++代碼內的分段錯誤(例如,當我迭代一系列對象及其子對象時)。我最好的假設是OpenGL以某種方式替代內存分配功能或做類似的不聖潔。任何人都可以看到這種情況?我會盡力根據要求提供更多細節,但整個事情似乎相當混亂。

根據要求,分離的測試用例:

生成文件:

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 

Python的文件:

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. 

C++的文件:

#include <boost/python.hpp> 
#include <boost/shared_ptr.hpp> 
#include <vector> 

namespace bp = boost::python; 

struct A { 
    typedef boost::shared_ptr<A> ptr; 
}; 

struct B { 
    typedef boost::shared_ptr<B> ptr; 
    std::vector<A::ptr> 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 >= 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_<ElementProxy> 
    wrap() 
    { 
     return bp::class_<ElementProxy>("ElementProxy", bp::no_init) 

      .def("__len__", &ElementProxy::len, 
       (bp::arg("self")), 
       "Returns the number of contained elements" 
       ) 

      .def("__getitem__", &ElementProxy::getitem, 
       (bp::arg("self"), bp::arg("i")), 
       "Returns the element at given index" 
       ) 

      .def("append", &ElementProxy::append, 
       (bp::arg("self"), bp::arg("element")), 
       "Appends an element" 
       ) 
      ; 
    } 

private: 

    B::ptr b_; 
}; 



BOOST_PYTHON_MODULE(foo) { 

    bp::class_<A, A::ptr, boost::noncopyable>("A") ; 

    ElementProxy::wrap(); 

    bp::class_<B, B::ptr, boost::noncopyable>("B") 
     .add_property("elements", &ElementProxy::init) ; 
} 
+1

你可以把它歸結爲一個最小的代碼示例?能夠看到它,並且可能對它進行測試,將有助於解決這個問題。 – quark 2009-11-17 20:14:31

+0

將問題修改爲包含一個。在這種特殊情況下,崩潰是在循環之後,在實際框架中,它發生在第一次「for」迭代之後。 感謝您的期待。 – 2009-11-17 21:00:43

+0

可能沒有直接幫助,但..一般認爲它是一個糟糕的主意做「從SomeModule導入*」。也許嘗試導入你需要的東西? – 2009-11-17 23:26:55

回答

2

如果您的OS是Linux,你可能是ru編入這個bug:https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/259219

如果啓動程序前調用

export LD_PRELOAD=<path-to-libstdc++>

修復它,就是它了。您需要更換機器上的實際路徑。像/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libstdc++.so.6。

該錯誤只發生在某些圖形驅動程序和發行版中,但它非常普遍。特別是,它已在Ubuntu 11.04中修復。