2009-11-17 5 views
1

Boost.Python으로 작성된 (거의) 완벽하게 작동하는 C++ 코드가 있습니다. 이것은 3 또는 4 클래스의 공유 포인터 기반 구조 계층 구조를 래핑합니다. 매우 복잡한 것은 아닙니다 (즉, 클래스 A는 클래스 B 인스턴스 포인터 등의 std :: vector를 가짐), 최상위 패키지는 foo라고합니다.Boost.Python + OpenGL 세분화 오류

얼마 전 PyOpenGL을 사용하여 시각화를 프로젝트에 추가하기로 결정했습니다. 그래서 지금 내가 import foo을 갖기 전에 import OpenGL을 가질 때마다 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 

파이썬 파일 :

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

+0

질문을 수정하도록 수정했습니다. 그 특별한 경우에, 크래시는 루프 이후입니다. 실제 프레임 워크에서, 그것은 첫 번째'for' 반복 이후에 발생합니다. 감사합니다. –

+0

직접적으로 도움이되지는 않을지 모르지만 일반적으로 "SomeModule import *"를 수행하는 것은 나쁜 생각으로 간주됩니다. 필요할 때 가져 오기를 시도 할 수 있습니까? –

답변

2

당신의 OS가 리눅스 인 경우, 너는 ru일지도 모른다. 이 버그에 적응하기 : 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에서 수정되었습니다.