2016-05-28 9 views
1

Каков правильный cythonic способ обернуть следующие функции-члены из boost::geometry::Point? Фрагмент кода происходит от here.Cythonic способ обертывания boost :: geometry :: Точки доступа

/// @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); 

Есть ли у кого-то более элегантное решение?

ответ

3

У вас возникают проблемы с обработкой 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 видит set0, вызванный на C, он заменяет set<0>, вызывая функцию шаблона напрямую. Затем вы можете использовать свойства, которые вы пытались сделать.

Это, вероятно, не намного лучше, чем создание вспомогательных функций, но это может быть немного проще.