Документация PyBindGen говорит о том, что легко написать собственные обработчики типов для ваших собственных типов данных. Однако я не нашел хороших примеров их написания. Примеры, которые поставляются с pybindgen, являются слишком простыми, чтобы понять детали, и документация, к сожалению, почти не существует.
Что мне нужно, это:
Есть ли какой-нибудь полный и хорошо документированный пример добавления собственного обработчика типов в pybindgen? Может быть, кто-то сделал это для вашего собственного проекта и может поделиться подходом?
Пример моей текущей привязки, чтобы лучше понять, что мне нужно. Сделано с Boost.python в настоящее время:
PyObject* System_getXYZ(System* s, int ind, int fr){
CREATE_PYARRAY_1D(p,3)
MAP_EIGEN_TO_PYARRAY(v,Vector3f,p)
v = s->XYZ(ind,fr);
return boost::python::incref(p);
}
...
class_<System, boost::noncopyable>("System", init<>())
...
.def("getXYZ", &System_getXYZ)
...
;
Метод System :: XYZ () возвращает объект Eigen :: Vector3f. Он должен быть преобразован в массив NumPy без копируя свои данные. Это важно, потому что вся идея связана с эффективностью.
В настоящее время это делается с помощью некрасивых макросов:
#define MAP_EIGEN_TO_PYARRAY(_matr,_T,_obj_ptr) \
if(!PyArray_Check(_obj_ptr)) throw pteros::Pteros_error("NumPy array expected!"); \
if(PyArray_TYPE(_obj_ptr)!=PyArray_FLOAT) throw pteros::Pteros_error("float NumPy array expected!"); \
Eigen::Map<_T> _matr((float*) PyArray_DATA(_obj_ptr), \
(PyArray_DIM((PyArrayObject*)_obj_ptr,0)==PyArray_Size(_obj_ptr)) ? PyArray_DIM(
(PyArray_DIM((PyArrayObject*)_obj_ptr,0)==PyArray_Size(_obj_ptr)) ? 1 : PyArray_#define CREATE_PYARRAY_1D(_ptr_obj, _dim1) \
PyObject* _ptr_obj; \
{ \
npy_intp _sz_dim1[1];\
_sz_dim1[0] = _dim1; \
_ptr_obj = PyArray_SimpleNew(1, _sz_dim1, PyArray_FLOAT); \
}
Это работает, но мне нужно написать функцию-обертку для каждого метода, который принимает Eigen-объекты, что является кошмаром для обслуживания. Вот почему я хочу попробовать PyBindGen и создать там конвертер, который автоматически добавляет весь стандартный код из этих макросов.
Кстати, конвертеры boost.python здесь не помогают, так как они принудительно копируют данные.
Задача ещё не решена.