使用pybind11完全透明地暴露Eigen :: Vector / Matrix类型

问题描述 投票:0回答:1

我有一个简单的类定义:

class State {
  private:
      Eigen::Vector3f m_data;

  public:
      State(const Eigen::Vector3f& state) : m_data(state) { }
      Eigen::Vector3f get() const { return m_data; }
      void set(const Eigen::Vector3f& _state) { m_data = _state; }
      std::string repr() const {
          return "state data: [x=" + std::to_string(m_data[0]) + ", y=" + std::to_string(m_data[1]) + ", theta=" + std::to_string(m_data[2]) + "]";
      }
};

然后我用pybind11在python中公开上面的内容:

namespace py = pybind11;

PYBIND11_MODULE(bound_state, m) {
    m.doc() = "python bindings for State";
    py::class_<State>(m, "State")
        .def(py::init<Eigen::Vector3f>())
        .def("get", &_State::get)
        .def("set", &_State::set)
        .def("__repr__", &_State::repr);
}

一切正常;我能够将此模块导入python并构造一个带有numpy数组的State实例。这不完全是我想要的。我希望能够访问这个对象,就好像它是一个numpy数组;我希望能够在python中执行以下操作:

import bound_state as bs
arr = np.array([1, 2, 3])
a = bs.State(arr)
print(a[0])

(以上抛出TypeError: 'bound_state.State' object does not support indexing

在过去,我使用boost :: python通过使用add_property来公开列表,这允许在C ++中对底层数据进行索引。 pybind11有类似的东西可以与Eigen一起使用吗?有人可以提供一个示例,说明如何公开可索引的State实例吗?

pybind11
1个回答
0
投票

根据API Docs,这可以使用def_property方法轻松完成。

把这个转过来:

namespace py = pybind11;

PYBIND11_MODULE(bound_state, m) {
    m.doc() = "python bindings for State";
    py::class_<State>(m, "State")
        .def(py::init<Eigen::Vector3f>())
        .def("get", &State::get)
        .def("set", &State::set)
        .def("__repr__", &State::repr);
}

进入:

namespace py = pybind11;

PYBIND11_MODULE(bound_state, m) {
    m.doc() = "python bindings for State";
    py::class_<State>(m, "State")
        .def(py::init<Eigen::Vector3f>())
        .def_property("m_data", &State::get, &State::set)
        .def("__repr__", &State::repr);
}

现在,从python方面,我可以做到:

import bound_state as bs
arr = np.array([1, 2, 3])
a = bs.State(arr)
print(a.m_data[0])

这不是我想要的,但是朝着正确的方向迈出了一步。

© www.soinside.com 2019 - 2024. All rights reserved.