#python #c #eigen #pybind11
#python #c #eigen #pybind11
Вопрос:
Я пытаюсь создать привязки к моему пользовательскому векторному классу, Vec3
который наследуется от класса matrix фиксированного размера Eigen::Vector3d
, имеет конструктор копирования и реализует некоторые дополнительные методы. Все работает нормально, пока я не попытаюсь вызвать метод производного класса, где я получаю incompatible function arguments
ошибку, хотя методы не принимают никаких аргументов.
Минимально воспроизводимый пример
bindings.cpp:
#include <Eigen/Core>
#include "pybind11/pybind11.h"
#include "pybind11/eigen.h"
namespace py = pybind11;
class Vec3 : public Eigen::Vector3d {
public:
Vec3() : Eigen::Vector3d() {}
Vec3(const Eigen::Vector3damp; v) : Eigen::Vector3d(v) {}
Vec3(int rows, int cols) : Vec3() {} // This constructor is needed for a problem-unrelated reason
int f() { return 123; } // I want to call this dummy method in python
};
PYBIND11_MODULE(Minimal, m) {
py::class_<Vec3>(m, "Vec3")
.def(py::init<>())
.def(py::init<const Eigen::Vector3damp;>())
.def("f", amp;Vec3::f);
}
Я использую pybind11 версии 2.4.3. CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(Minimal)
find_package(Eigen3 REQUIRED NO_MODULE)
set(PYBIND11_CPP_STANDARD -std=c 17)
set(PYBIND11_PYTHON_VERSION 3.6)
add_subdirectory(pybind11)
pybind11_add_module(Minimal "${CMAKE_CURRENT_LIST_DIR}/bindings.cpp")
target_link_libraries(Minimal PRIVATE Eigen3::Eigen)
После компиляции это результат:
$ python3 -c "from Minimal import Vec3; v = Vec3([0, 0, 0]); print(v.f());"
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: f(): incompatible function arguments. The following argument types are supported:
1. (self: numpy.ndarray[float64[3, 1]]) -> int
Invoked with: <Minimal.Vec3 object at 0x7f4561fd35a8>
Что еще я пробовал
Я подозревал, что pybind11, возможно, не понял, что Vec3
наследуется от Eigen::Vector3d
, поэтому я явно дал ему такое указание.
PYBIND11_MODULE(Minimal, m) {
py::class_<Eigen::Vector3d>(m, "Vector3d");
py::class_<Vec3, Eigen::Vector3d>(m, "Vec3")
.def(py::init<>())
.def(py::init<const Eigen::Vector3damp;>())
.def("f", amp;Vec3::f);
// These two lines also didn't help
// py::implicitly_convertible<Eigen::Vector3d, Vec3>();
// py::implicitly_convertible<Vec3, Eigen::Vector3d>();
}
К сожалению, я столкнулся с той же ошибкой, что и выше. Кто-нибудь может мне помочь?
Комментарии:
1. если вы попытаетесь удалить базовый класс Eigen::Matrix из Vec3 и сделать Vec3 автономным, сработает ли это тогда?
2. Это работает, но я должен наследовать от
Eigen::Matrix
из-за ограничений компании.
Ответ №1:
Попробуйте удалить или закомментировать: #включить «pybind11/eigen.h»
Комментарии:
1. Это решило мой первоначальный вопрос, но мне пришлось его обновить. Класс по-прежнему должен тесно взаимодействовать с Eigen:: Matrix (я хочу иметь возможность инициализировать его путем передачи вектора, и есть пользовательские методы, которые должны возвращать собственные объекты), поэтому я думаю, что я не могу обойтись без
python11/eigen.h
. Без собственного заголовка конструктор копирования завершается ошибкой с:incompatible constructor arguments. The following argument types are supported: [...] Minimal.Vec3(arg0: Eigen::Matrix<double, 3, 1, 0, 3, 1>)