Ошибки сегментации Boost.Python + OpenGL - PullRequest
1 голос
/ 17 ноября 2009

У меня есть (почти) отлично работающий код C ++, написанный с Boost.Python. Он оборачивает иерархию структуры, основанную на разделяемом указателе, из 3 или 4 классов, ничего страшного сложного (то есть класс A имеет std :: vector указателей экземпляра класса B и т. Д.), Пакет верхнего уровня, называемый, скажем, foo.

Некоторое время назад я решил добавить визуализацию в проект, используя PyOpenGL. Так что теперь, когда у меня есть import OpenGL до того, как у меня import foo, я получаю ошибки сегментации внутри кода C ++ (например, когда я перебираю последовательность объектов и их дочерних объектов).

Мое лучшее предположение заключается в том, что OpenGL каким-то образом заменяет функции выделения памяти или делает что-то подобное безобразно. Кто-нибудь может пролить свет на ситуацию? Я постараюсь предоставить более подробную информацию по запросу, но все это выглядит довольно хаотично.

По запросу, изолированный тестовый набор:

Makefile:

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 Ответ

2 голосов
/ 29 апреля 2011

Если ваша ОС Linux, вы можете столкнуться с этой ошибкой: https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/259219.

При звонке

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

перед запуском вашей программы это исправляет, вот и все. Вам нужно заменить фактический путь на вашем компьютере. Нечто подобное

Ошибка возникает только для некоторых графических драйверов и дистрибутивов, но она довольно широко распространена. В частности, это исправлено в Ubuntu 11.04.

...