pybind11:将c ++类(具有现有的python绑定)返回给python

时间:2019-02-25 17:02:44

标签: python c++11 vtk pybind11

我试图为c ++方法创建一个包装,该包装返回一个来自外部c ++库(vtk)的c ++类(vtkPolyData)。同一库具有可用的python绑定,该绑定已安装在我的python环境中。您如何告诉pybind C ++类(vtkPolydata)及其python变体相同?

我尝试使用此custom type caster macro。但我收到TypeError:Unable to convert function return value to a Python type! The signature was : (self: Versa3dLib.skeletonizer, offset distance: float) -> vtkPolyData

令人困惑,因为它看起来像转换映射到正确的类型,但是python无法解释它。所以我不确定什么地方出了问题,因为我也没有看到该宏有什么问题。我注意到在python中,vtkPolyData的类型为vtkCommonDataModelPython.vtkPolyData。这就是为什么转换不正确吗?

#include "skeletonizer.h"
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "PybindVTKTypeCaster.h"
#include <vtkSmartPointer.h>

namespace py = pybind11;

PYBIND11_VTK_TYPECASTER(vtkPolyData)
PYBIND11_DECLARE_HOLDER_TYPE(T, vtkSmartPointer<T>);

namespace pybind11 { namespace detail {
    template <typename T>
    struct holder_helper<vtkSmartPointer<T>> { // <-- specialization
        static const T *get(const vtkSmartPointer<T> &p) { return p.GetPointer(); }
    };
}}

PYBIND11_MODULE(Versa3dLib, m)
{
    py::class_<skeletonizer>(m, "skeletonizer")
        .def(py::init<vtkPolyData *>())
        .def("get_offset", &skeletonizer::get_offset,
             "return vtkPolyData offset",
             py::arg("offset distance"));
}

骨骼化器

#ifndef SKELETONIZER_H
#define SKELETONIZER_H

#include <vtkPolyData.h>
#include <vector>
#include <vtkSmartPointer.h>


using namespace std;

class skeletonizer
{
    public:
        skeletonizer(vtkPolyData* data);
        vtkSmartPointer<vtkPolyData> get_offset(double dist);
};

#endif

骨架化剂cpp

#include "skeletonizer.h"


skeletonizer::skeletonizer(vtkPolyData* data)
{
};

vtkSmartPointer<vtkPolyData> skeletonizer::get_offset(double dist)
{
    vtkSmartPointer<vtkPolyData> offsets = vtkSmartPointer<vtkPolyData>::New();

    return offsets;
};

1 个答案:

答案 0 :(得分:1)

我认为这应该是更通用的解决方案(希望更容易使用吗?):

我相信这应该通过以下方式对VTK代码进行改进:

  • 使用SFINAE概括类型转换程序(而不需要显式实例化...)。
  • 允许直接投射vtkSmartPointervtkNew(假设其中的类型是VTK类型)。

使代码类型遵循Drake's C++ + Python binding conventions

对于您所拥有的上述解决方案,我认为它已经很接近利用SMTK代码了,但是holder类型实例化是不正确的-您需要type_caster专业化的智能指针(vtk_pybind我发布的代码可以提供)。

我会看看是否可以在SMTK上发布问题,以了解他们是否要改进/简化其绑定代码(尤其是人们是否在使用它!)。

编辑:在此处发布问题:https://gitlab.kitware.com/cmb/smtk/issues/228