如何正确在pybind11中公开从Eigen :: Matrix派生的自定义Vector类? 最小可复制示例我还尝试了什么

问题描述

我试图创建对自定义向量类Vec3的绑定,该向量类继承自固定大小的矩阵类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::Vector3d& 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::Vector3d&>())
    .def("f",&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]); 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::f);

  // These two lines also didn't help
  // py::implicitly_convertible<Eigen::Vector3d,Vec3>();
  // py::implicitly_convertible<Vec3,Eigen::Vector3d>();
}

很不幸,我遇到了与上述相同的错误。有人可以帮我吗?

解决方法

尝试删除或注释掉:#include“ pybind11 / eigen.h”