2016-10-03 5 views
0

Я пишу C-расширения Python в библиотеку и хочу вернуть данные в виде массива Numpy. Библиотека имеет функцию, которая возвращает данные от датчика в структуру C. Я хотел бы взять данные из этой структуры и вернуть ее как массив Numpy.Возвращает данные из struct using Numpy Array

Определение структуры в библиотеке:

typedef struct rs_extrinsics 
{ 
    float rotation[9]; /* column-major 3x3 rotation matrix */ 
    float translation[3]; /* 3 element translation vector, in meters */ 
} rs_extrinsics; 

Прототип функции:

void rs_get_device_extrinsics(const rs_device * device, rs_stream from_stream, rs_stream to_stream, rs_extrinsics * extrin, rs_error ** error); 

Вот мой код, который просто пытается вернуть первое значение на данный момент:

static PyObject *get_device_extrinsics(PyObject *self, PyObject *args) 
{ 
    PyArrayObject *result; 
    int dimensions = 12; 

    rs_stream from_stream; 
    rs_stream to_stream; 
    rs_extrinsics extrin; 
    if (!PyArg_ParseTuple(args, "iiffffffffffff", &from_stream, &to_stream, &extrin)) { 
     return NULL; 
    } 

    result = (PyArrayObject *) PyArray_FromDims(1, &dimensions, PyArray_DOUBLE); 
    if (result == NULL) { 
     return NULL; 
    } 

    rs_get_device_extrinsics(dev, from_stream, to_stream, &extrin, &e); 
    check_error(); 
    result[0] = extrin.rotation[0]; 
    return PyArray_Return(result); 
} 

Я получаю следующую ошибку при компиляции:

error: assigning to 'PyArrayObject' (aka 'struct tagPyArrayObject_fields') from incompatible type 'float' 
result[0] = extrin.rotation[0]; 
     ^~~~~~~~~~~~~~~~~~~ 

ответ

0

PyArrayObject, помимо данных, есть несколько полей:

typedef struct PyArrayObject { 
    PyObject_HEAD 
    char *data; 
    int nd; 
    npy_intp *dimensions; 
    npy_intp *strides; 
    PyObject *base; 
    PyArray_Descr *descr; 
    int flags; 
    PyObject *weakreflist; 
} PyArrayObject; 

Вы должны получить данные поля данных из ваших PyArrayObjects. Например: result->data[index]; Также вам необходимо указать свои данные в соответствующем типе, указанном кодом символа result->descr->type. Также dims, вы переходите к PyArray, конструктор должен иметь тип npy_intp *, а не int. Тип массива в вашем случае должен быть NPY_DOUBLE.

Если вы вызываете свою функцию из python (вы?), Вам лучше просто передать объект списка из Python и использовать API PyList C для управления последовательностью с плавающей точкой.

PyObject*list_of_floats; 
PyArg_ParseTuple(args, "iiO", &from_stream, &to_stream, &list_of_floats);