【问题标题】:Writing a C++ simplifying wrapper for a C++ class with complex hierarchy so that Cython can call it为具有复杂层次结构的 C++ 类编写 C++ 简化包装器,以便 Cython 可以调用它
【发布时间】:2017-03-04 03:37:44
【问题描述】:

我正在尝试为 C++ 计算拓扑库 GUDHI (http://gudhi.gforge.inria.fr) 设计 Cython 包装器。 GUDHI 类将其他类作为它们的参数,这些类将其他子类传递给它们的方法。直接推到 Cython 相当混乱。我在下面有一个代码示例。

我向 cython google 小组发布了一个问题,有人建议我用 C++ 编写一个简化的包装器,以向 Cython 隐藏这种复杂性。评论的text在下方。

如果事情变得复杂,另一种选择是用 C++ 编写简化包装器并调用它们。 (在 Cython 支持任何 C++ 之前,这曾经是必需的,并且如果使用深奥的 C++ 功能仍然很有用,即使它只是简单地声明几个 typedef。在下面的代码中,它定义(并取消定义和重新定义(!))宏来处理非常冗长的代码,这可能是您最好的选择。)您还可以执行强制转换 [1](动态或其他)以在 Cython 不知道相关的类型之间进行转换。

这是一个代码示例,可让您了解所涉及的层次结构。

typedef CGAL::Epick_d< CGAL::Dimension_tag<2> > Kernel;

--- needs to be passed into


Gudhi::alpha_complex::Alpha_complex<Kernel> alpha_complex_from_points(points, alpha_square_max_value);

Epick_d.h

--- Epick_d.h depends upon these libraries

#include <CGAL/NewKernel_d/Cartesian_base.h>
#include <CGAL/NewKernel_d/Cartesian_static_filters.h>
#include <CGAL/NewKernel_d/Cartesian_filter_K.h>
#include <CGAL/NewKernel_d/Wrapper/Cartesian_wrap.h>
#include <CGAL/NewKernel_d/Kernel_d_interface.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/Interval_nt.h>

--- Sample source code for Epick_d.h

namespace CGAL {
#define CGAL_BASE \
Cartesian_filter_K< Cartesian_base_d<double, Dim>, \
Cartesian_base_d<Interval_nt_advanced, Dim>, \
Cartesian_base_d<internal::Exact_field_selector<double>::Type, Dim> \
>
template<class Dim>
struct Epick_d_help1
: CGAL_BASE
{
CGAL_CONSTEXPR Epick_d_help1(){}
CGAL_CONSTEXPR Epick_d_help1(int d):CGAL_BASE(d){}
};
#undef CGAL_BASE
#define CGAL_BASE \
Cartesian_static_filters<Dim,Epick_d_help1<Dim>,Epick_d_help2<Dim> >
template<class Dim>
struct Epick_d_help2
: CGAL_BASE
{
CGAL_CONSTEXPR Epick_d_help2(){}
CGAL_CONSTEXPR Epick_d_help2(int d):CGAL_BASE(d){}
};
#undef CGAL_BASE
#define CGAL_BASE \
Kernel_d_interface< \
Cartesian_wrap< \
Epick_d_help2<Dim>, \
Epick_d<Dim> > >
template<class Dim>
struct Epick_d
: CGAL_BASE
{
CGAL_CONSTEXPR Epick_d(){}
CGAL_CONSTEXPR Epick_d(int d):CGAL_BASE(d){}
};
#undef CGAL_BASE
}
#endif

我不确定如何设计一个与 Cython 兼容的 C++ 包装器,但也会对 Cython 隐藏层次结构。

这是我的想法,但我不确定这是否是简化包装器的意思。所以一个 GUDHI 类接受一个 n 维点数组,然后对它们进行一些几何计算。所以现在如果我想直接包装一个 GUDHI 类,例如Simplex_tree(subclass),那么我需要通知 Cython。相反,我可以编写一个 C++ 类,它只获取点数组,计算结果,然后返回一个数组。所以在一些伪代码中类似于

Class(*array)

     constructor(*array)

       loop: 

            take values from *array and create CGAL::Point_d

            push new CGAL::Point_d to std::vector<CGAL::Point_d>

       include all of the hierarchical class operations here.

     method_1(std::vector)

       include all of the hierarchical operations here, but
       return the result as a simple array or struct.

然后我是否能够在 cython 中包装这个类而不必传递所有的类层次结构,因为我只是将一个数组指针传递给函数?

【问题讨论】:

    标签: c++ python-3.x wrapper cython


    【解决方案1】:

    这是上次GUDHI version 2.0.0 所做的。 包装类 Alpha_complex_interface(不再模板化)包装 Alpha_complex> 以在每个维度上工作。 然后类 Alpha_complex_interface 被cythonized(参见 alpha_complex.pyx) 然后通过std::vector>&交换点。 如果您对我做的方式有任何疑问,或者您需要其他接口,请不要犹豫。

    【讨论】:

      猜你喜欢
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-15
      相关资源
      最近更新 更多