我有一个内部C ++库,我已经使用Boost.Python成功地向Python公开了这个库。它接受用户创建的Python对象,然后在该对象中使用某些方法来执行某些任务,并且它在大多数情况下都能正常工作。
该库的Python使用如下:
class Foo(object):
def __init__(self, args):
"""create an instance of this class with instance-specific attributes"""
def Bar1(self, a, b, c):
"""do something with the given integers a, b and c"""
return a + (b*c)
def Bar2(self, a, b, c):
"""do something else with the given integers a, b and c"""
print (a*b) + c
import mylib
cheese = mylib.Wine()
qux = Foo()
cheese.setup(qux)
cheese.do_something(1)
cheese.do_something(2)
C ++中的“Wine”对象如下所示:
#include <boost/python.h>
#include <Python.h>
class Wine {
public:
Wine() {};
~Wine() {};
void setup(boost::python::object baz) {
baz_ = baz;
};
static void do_something(boost::python::object pyreq) {
int request = boost::python::extract<int>(pyreq);
int a = 1;
int b = 2;
int c = 3;
if (request == 1) {
int d = boost::python::extract<int>(baz_.attr("Bar1")(a, b, c));
};
else if (request == 2) {
baz_.attr("Bar2")(a, b, c);
};
};
private:
static boost::python::object baz_;
};
BOOST_PYTHON_MODULE(mylib)
{
using namespace boost::python;
class_<Wine>("Wine")
.def("do_something", &Wine::do_something)
.staticmethod("do_something")
.def("setup", &Wine::setup)
;
};
问题在于,在成功执行所有任务后,程序终止于SegFault。这并不是什么大不了的事,因为我需要执行的代码仍然执行,而我需要执行的任务都已执行。 SegFault仅在销毁此C ++“Wine”对象时发生。不过,这是一个不优雅的结果,我想解决这个问题。
我从在线搜索中收集的内容暗示这是对Python的所有权声明不当的问题。最终结果是C ++析构函数被称为两次,第二次调用导致SegFault。
不幸的是到目前为止我还没能解决问题。可用的文档仅涵盖基础知识,我无法复制其他人使用boost智能指针和C ++中的一些花哨的声明/破坏技巧所取得的成功。任何指导都将非常感谢。
答案 0 :(得分:0)
问题是静态Wine::baz_
对象在静态/全局破坏期间被破坏。这是在Python运行时最终确定之后,但由于boost::python::object
使用Python C-API,因此它的销毁需要有效的Python运行时(尽管object
引用None
时可能不行。通过在Python完成之前安排baz_
被销毁,你应该能够避免段错误。总体上最干净的方法可能是使baz_
成为非静态成员变量。