【问题标题】:Cythonic way to wrap boost::geometry::Point accessors包装 boost::geometry::Point 访问器的 Cythonic 方式
【发布时间】:2016-05-28 23:18:18
【问题描述】:

包装boost::geometry::Point 的以下成员函数的正确 cythonic 方式是什么?代码 sn-p 来自here

    /// @brief Get a coordinate
    /// @tparam K coordinate to get
    /// @return the coordinate
    template <std::size_t K>
    inline CoordinateType const& get() const
    {
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
        BOOST_GEOMETRY_ASSERT(m_created == 1);
        BOOST_GEOMETRY_ASSERT(m_values_initialized[K] == 1);
#endif
        BOOST_STATIC_ASSERT(K < DimensionCount);
        return m_values[K];
    }

    /// @brief Set a coordinate
    /// @tparam K coordinate to set
    /// @param value value to set
    template <std::size_t K>
    inline void set(CoordinateType const& value)
    {
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
        BOOST_GEOMETRY_ASSERT(m_created == 1);
        m_values_initialized[K] = 1;
#endif
        BOOST_STATIC_ASSERT(K < DimensionCount);
        m_values[K] = value;
    }

我第一次尝试使用:

cdef extern from "s57/data/geometries.h" namespace "bg::model":
    cdef cppclass _Geo2 "bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree>>":
        _Geo2()
        _Geo2( const _Geo2& other )
        const double get[size_t]() except +
        void set[size_t](double) except +

但是我不知道去哪里,因为这样的事情:

property x:
    def __set__(self, double value):
        deref(self._p).set[0](value)

给了我这个失败:

Error compiling Cython file:
------------------------------------------------------------
...
    property x:
        def __set__(self, double value):
            deref(self._p).set[0](value)
                              ^
------------------------------------------------------------

c:\XXXX\x.pyx:24:31: not parsable as a type

我目前的工作解决方案是创建一些辅助函数,例如:

double get_geo2_x( geo2& pnt );
double get_geo2_y( geo2& pnt );
void set_geo2_x( geo2& pnt, double value );
void set_geo2_y( geo2& pnt, double value );

有人想出一个更优雅的解决方案吗?

【问题讨论】:

    标签: c++ boost cython boost-geometry python-bindings


    【解决方案1】:

    您遇到了 Cython 处理非类型模板参数的问题。可以使用字符串手动指定函数名,直接插入到生成的C代码中(见http://docs.cython.org/src/userguide/external_C_code.html#resolving-naming-conflicts-c-name-specifications

    作为一个非常简单的例子

    // example.hpp
    #include <iostream> 
    
    class C {
      template <int K>
      void set(double value) {
          std::cout << K << ": " << value << std::endl;
      }
    

    还有 Cython 代码

    cdef extern from "example.hpp":
        cdef cppclass C:
            void set0 "set<0>"(double) except +
            void set1 "set<1>"(double) except + 
    
    
    def do_set():
        # very simple illustrative example
        cdef C c
        c.set0(1.0)
        c.set1(1.5)
    }
    

    每当 Cython 看到在 C 上调用 set0 时,它都会替换 set&lt;0&gt;,直接调用模板函数。然后,您可以像尝试做的那样使用属性。

    这可能并不比创建辅助函数好很多,但可能会更容易一些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-06-05
      • 2014-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多