pybind11 自定义类型分段错误
pybind11 custom type segmentation fault
我尝试用 pybind11 编写 python 绑定。因为我还需要非简单 python 类型,所以我必须创建自定义类型脚轮。我的问题是每当我打电话
get_point
从 python 将返回 LPoint2d,但以下命令将导致分段错误。
据我了解,python 引用计数可能会导致该错误。但是由于我对 pybind11 很陌生,所以我不确定。我该如何避免该错误?
在下面的示例中,我使用了 panda3d
中的 LPoint2d
作为示例类型。但错误也会发生在其他类型上(例如 cv2.KeyPoint)。
Python:
>>> from panda3d.core import LPoint2d
>>> import test_module as tm
>>> foo = tm.Test()
>>> foo.get_point()
LPoint2d(0, 0)
>>> bar = 42
Segmentation fault (core dumped)
C++代码:
#include <pybind11/pybind11.h>
#include <panda3d/lpoint2.h>
class Test
{
public:
Test(){}
LPoint2d getPoint(){
return m_point;
}
void setPoint(LPoint2d &p){
m_point = p;
}
private:
LPoint2d m_point;
};
namespace py = pybind11;
namespace pybind11 { namespace detail {
template <> struct type_caster<LPoint2d> {
public:
PYBIND11_TYPE_CASTER(LPoint2d, _("LPoint2d"));
bool load(handle src, bool) {
value = LPoint2d(4,2);
return true;
}
static handle cast(const LPoint2d &lp, return_value_policy, handle defval) {
py::object p3d = py::module::import("panda3d.core");
py::object plp = p3d.attr("LPoint2d")(lp.get_x(), lp.get_y());
return {plp.ptr()};
}
};
}}
PYBIND11_MODULE(test_module, m) {
py::class_<Test>(m, "Test")
.def(py::init<>())
.def("get_point", &Test::getPoint)
.def("set_point", &Test::setPoint)
;
}
似乎只要增加引用计数器就可以解决这个问题。
static handle cast(const LPoint2d &src, return_value_policy policy, handle parent) {
py::object p3d = py::module::import("panda3d.core");
py::object plp = p3d.attr("LPoint2d")(src.get_x(), src.get_y());
plp.inc_ref();
return plp.ptr();
}
这可能不是一个好的解决方案,但目前看来还可以。
我尝试用 pybind11 编写 python 绑定。因为我还需要非简单 python 类型,所以我必须创建自定义类型脚轮。我的问题是每当我打电话
get_point
从 python 将返回 LPoint2d,但以下命令将导致分段错误。
据我了解,python 引用计数可能会导致该错误。但是由于我对 pybind11 很陌生,所以我不确定。我该如何避免该错误?
在下面的示例中,我使用了 panda3d
中的 LPoint2d
作为示例类型。但错误也会发生在其他类型上(例如 cv2.KeyPoint)。
Python:
>>> from panda3d.core import LPoint2d
>>> import test_module as tm
>>> foo = tm.Test()
>>> foo.get_point()
LPoint2d(0, 0)
>>> bar = 42
Segmentation fault (core dumped)
C++代码:
#include <pybind11/pybind11.h>
#include <panda3d/lpoint2.h>
class Test
{
public:
Test(){}
LPoint2d getPoint(){
return m_point;
}
void setPoint(LPoint2d &p){
m_point = p;
}
private:
LPoint2d m_point;
};
namespace py = pybind11;
namespace pybind11 { namespace detail {
template <> struct type_caster<LPoint2d> {
public:
PYBIND11_TYPE_CASTER(LPoint2d, _("LPoint2d"));
bool load(handle src, bool) {
value = LPoint2d(4,2);
return true;
}
static handle cast(const LPoint2d &lp, return_value_policy, handle defval) {
py::object p3d = py::module::import("panda3d.core");
py::object plp = p3d.attr("LPoint2d")(lp.get_x(), lp.get_y());
return {plp.ptr()};
}
};
}}
PYBIND11_MODULE(test_module, m) {
py::class_<Test>(m, "Test")
.def(py::init<>())
.def("get_point", &Test::getPoint)
.def("set_point", &Test::setPoint)
;
}
似乎只要增加引用计数器就可以解决这个问题。
static handle cast(const LPoint2d &src, return_value_policy policy, handle parent) {
py::object p3d = py::module::import("panda3d.core");
py::object plp = p3d.attr("LPoint2d")(src.get_x(), src.get_y());
plp.inc_ref();
return plp.ptr();
}
这可能不是一个好的解决方案,但目前看来还可以。