Eigen :: Matrix, содержащийся внутри структуры, помечен pybind11 как не записываемый

Я использую pybind11 для создания привязки Python для моей библиотеки C ++, которая использует типы Eigen. Однако, когда я пытаюсь связать структуру, содержащую Eigen::Matrix, соответствующий сгенерированный класс Python содержит все элементы ndarray (целевой класс Python для Eigen::Matrix членов) с флагом Writeable, установленным в значение false, которые, следовательно, не подлежат изменению. Мне удалось свести мою проблему к следующему MWE:

// binding.cpp
#include "Eigen/Dense"
#include "pybind11/pybind11.h"
#include "pybind11/eigen.h"

struct Example {
   Eigen::Matrix<double, 3, 1> m;
};

namespace py = pybind11;
PYBIND11_MODULE(MyBinding, m)
{
   py::class_<Example>(m, "Example")
      .def(py::init<>())
      .def_readwrite("m", &Example::m);
}
# script.py
import MyBinding
ex = MyBinding.Example()
# ex.m has Writeable flag equal to false!

Напротив, при связывании следующего кода все работает так, как ожидалось, т.е. значение, возвращаемое f при вызове в Python, является изменяемым (для флага Writeable установлено значение true):

Eigen::Matrix<double,3,1> f() {
   return {};
}

PYBIND11_MODULE(MyBinding, m)
{
   m.def("f", &f);
}

Что мне здесь не хватает? Спасибо за любую помощь!


person Rackbox    schedule 13.09.2019    source источник


Ответы (1)


def_readwrite - это ярлык для def_property source11.h#L1185-L1192"> relferrere"nbindl="nl1192"> relferrer, где геттер берет экземпляр класса по константной ссылке. Следовательно, результирующий массив numpy не подлежит изменению.

Все, что вам нужно сделать, это написать собственные функции получения и установки:

namespace py = pybind11;
PYBIND11_MODULE(MyBinding, m)
{
   py::class_<Example>(m, "Example")
      .def(py::init<>())
      .def_property("m", 
           [](Example& example){ return example.m; } // getter 
           [](Example& example, const Eigen::Matrix<double, 3, 1>& value ){ // setter
             example.m = value;
           }
);
}

Внимание! непроверенный код, вам может потребоваться передать дополнительный аргумент политики возвращаемого значения.

person Sergei    schedule 13.09.2019