pybind11:return c++ class(具有现有的 python 绑定)到 python
pybind11: return c++ class (with an existing python binding) to python
我正在尝试为 returns 来自外部 c++ 库 (vtk) 的 c++ class(vtkPolyData) 的 c++ 方法创建包装器。同一个库有 python 绑定可用,它已经安装在我的 python 环境中。您如何告诉 pybind c++ class (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;
};
我认为这应该是一个更通用的解决方案(希望更容易使用?):
我相信这应该是对 VTK 代码的改进:
- 使用 SFINAE 概括类型转换(而不是要求显式实例化...)。
- 允许直接转换
vtkSmartPointer
和 vtkNew
(假设其中的类型是 VTK 类型)。
使代码类似于 Drake's C++ + Python binding conventions。
对于您拥有的上述解决方案,我认为它已接近利用 SMTK 代码,但持有者类型实例化不正确 - 您需要 type_caster
智能指针的特化(vtk_pybind
我 posted 会提供的代码)。
我会看看我是否可以 post 关于 SMTK 的问题,看看他们是否想改进/简化他们的绑定代码(尤其是如果人们引用它!)。
我正在尝试为 returns 来自外部 c++ 库 (vtk) 的 c++ class(vtkPolyData) 的 c++ 方法创建包装器。同一个库有 python 绑定可用,它已经安装在我的 python 环境中。您如何告诉 pybind c++ class (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;
};
我认为这应该是一个更通用的解决方案(希望更容易使用?):
我相信这应该是对 VTK 代码的改进:
- 使用 SFINAE 概括类型转换(而不是要求显式实例化...)。
- 允许直接转换
vtkSmartPointer
和vtkNew
(假设其中的类型是 VTK 类型)。
使代码类似于 Drake's C++ + Python binding conventions。
对于您拥有的上述解决方案,我认为它已接近利用 SMTK 代码,但持有者类型实例化不正确 - 您需要 type_caster
智能指针的特化(vtk_pybind
我 posted 会提供的代码)。
我会看看我是否可以 post 关于 SMTK 的问题,看看他们是否想改进/简化他们的绑定代码(尤其是如果人们引用它!)。