【发布时间】:2009-11-17 20:05:13
【问题描述】:
我有一个用 Boost.Python 编写的(几乎)完美运行的 C++ 代码。它包装了一个基于共享指针的 3 或 4 个类的结构层次结构,没有什么非常复杂的(即 A 类有一个 B 类实例指针的 std::vector 等),称为 foo 的顶级包。
前段时间,我决定使用 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
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) ;
}
【问题讨论】:
-
你能把它归结为一个最小的代码示例吗?能够查看它并可能对其进行测试,将有助于弄清楚它。
-
将问题修改为包含一个。在这种特殊情况下,崩溃发生在循环之后,在实际框架中,它发生在第一次
for迭代之后。感谢收看。 -
可能没有直接帮助,但是.. 通常认为“从 SomeModule 导入 *”是个坏主意。也许尝试只导入你需要的东西?
-
好建议,但仍然没有运气:((即
from OpenGL import GL仍然崩溃)
标签: python memory opengl boost segmentation-fault