Найти - Пользователи
Полная версия: boost::python завернуть boost::array
Начало » Python для новичков » boost::python завернуть boost::array
1 2 3 4
Обедающий философ
Андрей Светлов
Какое время жизни у Cell? Кто удаляет?
Никто не удаляет. Они все остаются до конца выполнения программы. Там один объект типа World, а в нём куча других объектов с указателями, но концептуально они все внутри ворлда. Возможно, я таки напишу удаление - тогда они будут все вместе удаляться вместе с ворлдом.

Андрей Светлов
Что будет, если вы куда-то этот Cell* присвоите?
А что при этом может быть?

Андрей Светлов
Вектора не нужны — достаточно простого класса-обертки.
Можно пример?

Андрей Светлов
Сколько элементов у float*
Максимум - порядка нескольких десятков, варьируется от запуска к запуску, но в рамках одного запуска константа. Есть ещё другие типы массивов, там поменьше - два и четыре элемента.
Обедающий философ
doza_and
Если надо пишите сюда или в личку могу полностью работающий пример прислать.  Но int a я вам не смогу завернуть….
Ежели не секрет, запостите прямо здесь. И чем int a принципиально отличается от float a?
doza_and
разница есть между array<float,3> и float
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/array.hpp>
const int NC=6;


using namespace boost::python;

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( !(0<=a<N && 0<b<=N) )
{
PyErr_SetString(PyExc_KeyError,"index out of range");
throw_error_already_set();
}
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( !(0<=a<N && 0<b<=N) )
{
PyErr_SetString(PyExc_KeyError,"index out of range");
throw_error_already_set();
}
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,return_value_policy<copy_non_const_reference>())
.def("__getitem__",&_arrayN<float,NC>::get)
.def("__getslice__",&_arrayN<float,NC>::getslice)
.def("__setslice__",&_arrayN<float,NC>::setslice)
.def("__setitem__",&_arrayN<float,NC>::set)
.def("values", &_arrayN<float,NC>::values)
;
}
Всетаки пришлось мусор порезать, надеюсь будет компилироваться. (msvc10,Boost 1.47.0)
Обедающий философ
Премного благодарен. Только непонятно, почему это нельзя под обычные массивы переделать. Завтра попробую.

И как передавать в питон указатели - я тоже так и не понял.
Обедающий философ
Нашёл, как поступать с указателями. http://stackoverflow.com/questions/2541446/exposing-a-pointer-in-boost-python Автору повезло, он это всего за десять минут нашёл.

        .add_property("cell",
make_getter(&Agent::cell, return_value_policy<reference_existing_object>()),
make_setter(&Agent::cell, return_value_policy<reference_existing_object>()))
Андрей Светлов
У автора плохой дизайн. Когда и как будет удаляться Tree.head?
Обедающий философ
Эээ.. Как вы на основании трёх строк кода поняли, что дизайн плохой? И как должен выглядеть хороший дизайн?
Андрей Светлов
Самое простое — заменить Node* на shared_ptr<Node>. Эта штука отлично совмещается с питоновским счетчиком ссылок.
Обедающий философ
Боюсь, я пока что к этому морально не готов. Да и скорость наверняка упадёт.

Также следующая проблема вскрылась:

In [18]: world.cells[0][3].agent_n
Out[18]: 2

In [19]: map(lambda a: a.agent_n, world.cells[0])
---------------------------------------------------------------------------
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*
То бишь когда я просто обращаюсь к элементу - то всё хорошо, а когда через map или reduce - то всё плохо. World.cells следующего типа:

typedef vector <Cell *> Row;

typedef vector <Row> Grid;

..............


class_< Row >("Row")
.def(vector_indexing_suite< Row >())
;

class_< Grid >("Grid")
.def(vector_indexing_suite< Grid >())
;
Обедающий философ
Я щас заплачу.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB