Форум сайта python.su
Не получается по человечески завернуть массив фиксированной длины. Если кто делал поделитесь кодом.
Из мелочной любви к экономии решил в классе использовать
class Ta
{
public:
boost::array<float,3> x
};
class_<std::vector<float> >("FloatVec")
.def(vector_indexing_suite<std::vector<float> >())
;
class_<Tarr3>("Vec3")
.def("__getitem__",&(Tarr3::operator[]))
;
template<class T,int N>
class Tcv:public boost::array<T,N>
{
public:
T getitem(int i)const {return (*this)[i];}
void setitem(int i,const T& v){(*this)[i]=v;}
T len() const {return N;}
};
class_<TcvNC>("TcvNC")
.def("__getitem__",&TcvNC::getitem)
.def("__setitem__",&TcvNC::setitem)
.def("__len__",&TcvNC::len)
;
Отредактировано (Июль 30, 2011 20:26:27)
Офлайн
Оказалось проще прилепить функции с другими именами. Оно и полезнее когда раcширяешь функциональность данного класса
typedef boost::array<float,NC> Tarr6;
template<class T, int N>
struct _arrayN
{
typedef boost::array<T,N> arrayN;
static T get(arrayN const& self, int idx)
{
if( 0<=idx && idx<N ) return self[idx];
PyErr_SetString(PyExc_KeyError,"index out of range");
throw_error_already_set();
}
static boost::python::list getslice(arrayN const& self, int a,int b)
{
if(b>N){b=N;}
if(a<0){a=0;}
boost::python::list t;
for(int i=a;i<b;++i)
t.append(self[i]);
return t;
}
static void setslice(arrayN& self, int a,int b,boost::python::object& v)
{
if(b>N){b=N;}
if(a<0){a=0;}
for(int i=a;i<b;++i)
self[i]=extract<float>(v[i]);
}
static void set(arrayN& self, int idx, const T val) { self[idx]=val; }
static boost::python::list values(arrayN const& self)
{
boost::python::list t;
for(int i=0;i<N;++i)
t.append(self[i]);
return t;
}
static int size(arrayN const & self)
{
return NC;
}
};
BOOST_PYTHON_MODULE(rbt10)
{
class_<Tarr6>("Tarr6")
.def("__len__", &_arrayN<float,NC>::size)
.def("__getitem__",&_arrayN<float,NC>::get)
.def("__getslice__",&_arrayN<float,NC>::getslice)
.def("__setslice__",&_arrayN<float,NC>::setslice)
.def("__setitem__",&_arrayN<float,NC>::set)
;
}
Отредактировано (Авг. 17, 2011 08:35:12)
Офлайн
А у меня обычные массивы не обёртываются.
Офлайн
Везет вам. Может еще и sip попробовать? Он получше swig будет?
Офлайн
Это вы мне? Я же буст питон использую, согласно вашему же совету.
Вопщем, у меня не заворачиваются самые обычные массивы (скажем, int a;). Сколько ни искал - не смог ничего найти. Не поверю, что хвалёный буст для такого простого случая не может ничего предложить.
А теперь у меня ещё не заворачивается структура, точнее, вектор структур.
typedef bool (Agent::* action_func) () ;
struct pricelist {
action_func action;
real price;
};
............
class_< pricelist >("pricelist")
.def_readwrite("action", &pricelist::action)
.def_readwrite("price", &pricelist::price)
;
class_< vector <pricelist> >("action_vector")
.def(vector_indexing_suite< vector <pricelist> >())
;
Отредактировано (Авг. 17, 2011 14:57:15)
Офлайн
Для векторов нужно использовать indexing suite: http://www.boost.org/doc/libs/1_47_0/libs/python/doc/v2/indexing.html
Для того, чтобы завернуть функцию, возвращающую указатель — нужно прописать return value policy, который расскажет как с этим указателем нужно поступать при decref.
Офлайн
А можно поподробнее? Хотя бы ссылки на примеры. Об return_value_policy вроде нашёл http://wiki.python.org/moin/boost.python/CallPolicy#return_value_policy.3CT.3E , однако там почему-то говорится, что reference_existing_object суть naïve (dangerous) approach, а какая ему альтернатива - я не понял.
Также у меня теперь указатели (и массивы соответственно) не понимаются питоном:
In [7]: a.outputs
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/media/3f16c67b-5e31-48bf-85c2-65bfd35e49f3/250gb/dima/alife/model/<ipython console> in <module>()
TypeError: No to_python (by-value) converter found for C++ type: float*
.........
In [44]: a.cell
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/media/3f16c67b-5e31-48bf-85c2-65bfd35e49f3/250gb/dima/alife/model/<ipython console> in <module>()
TypeError: No to_python (by-value) converter found for C++ type: Cell*
Офлайн
Правильно пишут. Что вы хотите увидеть? Есть метод Cell* meth();
Какое время жизни у Cell? Кто удаляет? Что будет, если вы куда-то этот Cell* присвоите?
Вектора не нужны — достаточно простого класса-обертки. Сколько элементов у float* (это вдогонку к предыдущим вопросам)?
Офлайн
Ну у меня известно сколько элементов у float* - 3
Про indexing suite я наверное нечетко написал. Обычный sute заточен под наличие операций удаления элементов, а мой базовый тип boost::array<float,3> этого не умеет в принципе - он не контейнер он обеспечивает только доступ по индексу и слайсинг. Поэтому indexing suite валится(те не компилируется
).
Обедающий философэто потому float a и float* a; при передаче в функцию - почти одно и тоже.
Вопщем, у меня не заворачиваются самые обычные массивы
Обедающий философЕсли надо пишите сюда или в личку могу полностью работающий пример прислать. Но int a я вам не смогу завернуть….
А можно поподробнее?
Офлайн
doza_and, как раз с вашим примером все хорошо и ясно
Офлайн