Python C привязка - получить массив из python в C ++ - PullRequest
1 голос
/ 06 января 2020

Как гласит заголовок: я хотел бы сделать привязку python в C ++, которая выполняет некоторые алгебраические операции c над некоторым массивом. Для этого мне нужно проанализировать python «объект массива» в C ++ как вектор двойного или целого числа или любого другого случая. Я пытался сделать это, но я столкнулся с некоторыми проблемами. Я создал новый тип python и класс с именем Typer, где у меня есть этот метод, который пытается получить элементы массива python, а затем вычислить сумму (в качестве первого шага).

tatic PyObject *Typer_vectorsum(Typer *self, PyObject *args)
{
    PyObject *retval;
    PyObject *list;

    if (!PyArg_ParseTuple(args, "O", &list))
        return NULL;
    double *arr;
    arr = (double *)malloc(sizeof(double) * PyTuple_Size(list));
    int length;
    length = PyTuple_Size(list);
    PyObject *item = NULL;
    for (int i = 0; i < length; ++i)
    {
        item = PyTuple_GetItem(list, i);
        if (!PyFloat_Check(item))
        {
            exit(1);
        }
        arr[i] = PyFloat_AsDouble(item);
    }
    double result = 0.0;
    for (int i = 0; i < length; ++i)
    {
        result += arr[i];
    }
    retval = PyFloat_FromDouble(result);
    free(arr);
    return retval;
}

В этом методе я анализирую объект массива python в массив C (выделяя память массива с помощью mallo c). Затем я добавляю каждый элемент объекта в мой массив C и просто вычисляю сумму в последнем для -l oop.

Если я соберу проект, а затем создаю тестовый файл python, ничего не происходит (файл компилируется без проблем, но ничего не печатается).

y = example.Typer() .  #typer is the init
tuple = (1, 2, 3)
print(y.vectorsum(tuple))

Я что-то упустил? А также, есть ли хороший и простой способ получить объект массива python в C ++, но как std :: vector вместо массива classi c C?

Заранее спасибо !

1 Ответ

1 голос
/ 07 января 2020

Кортеж содержит целые числа, а не числа с плавающей запятой, поэтому ваш PyFloat_Check не может быть выполнен. И нет, прямого набора из массива Python в массив C или C ++ std::vector нет. Причина в том, что кортеж - это массив Python объектов, а не массив C значений, таких как double s.

Вот ваш пример с улучшенной проверкой ошибок, после которой он должен работать:

PyObject *retval;
PyObject *list;

if (!PyArg_ParseTuple(args, "O!", &PyTuple_Type, &list))
    return NULL;

double *arr = 
arr = (double *)malloc(sizeof(double) * PyTuple_GET_SIZE(list));
int length;
length = PyTuple_GET_SIZE(list);
PyObject *item = NULL;
for (int i = 0; i < length; ++i)
{   
    item = PyTuple_GET_ITEM(list, i);
    arr[i] = PyFloat_AsDouble(item);
    if (arr[i] == -1. && PyErr_Occurred())
    {   
        exit(1);
    }
}
double result = 0.0;
for (int i = 0; i < length; ++i)
{
    result += arr[i];
}
retval = PyFloat_FromDouble(result);
free(arr);
return retval;
...