Динамический размер массива объектов в Cython - PullRequest
0 голосов
/ 24 июня 2018

Как я могу выполнить эквивалент следующего кода C ++ в Cython ?

typedef vector<double> dvec;
dvec *arr = new dvec[n]; // n is an unsigned int (unknown at compile time)

// do something with arr; for example...
arr[0].push_back(10);
cout << arr[0][0] << endl;

Я пытался распределить память по n векторам, но тогда я не знаю, как сделать новое размещение в Cython. Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

В дополнение к ответу @ DavidW: начиная с Cython 0.28 появилась новая функция, позволяющая дословный C-код .Его преимуществом является беспроблемное использование таких маленьких C / C ++ - оболочек:

cdef extern from *:
    """
    template <typename T>
    T* array_new(int n) {
        return new T[n];
    }

    template <typename T>
    void array_delete(T* x) {
        delete [] x;
    }
    """
    T* array_new[T](int)
    void array_delete[T](T* x)

from libcpp.vector cimport vector
.... and so on

без необходимости создания внешнего заголовочного файла.

0 голосов
/ 24 июня 2018

Не похоже, что вы можете создать новый массив (new something[n]) в Cython.Простейшим решением было бы создать 1-строчную функцию C ++ для создания нового массива и удаления массива, а затем вызывать их.

template <typename T>
T* array_new(int n) {
    return new T[n];
}

template <typename T>
void array_delete(T* x) {
    delete [] x;
}

Вызывается из следующего файла Cython

# distutils: language = c++

from libcpp.vector cimport vector

ctypedef vector[double] dvec

cdef extern from "cpp_funcs.hpp":
    T* array_new[T](int)
    void array_delete[T](T* x)

def example(int n):
    cdef dvec* arr = array_new[dvec](n)
    try:
        if n>0:
            arr[0].push_back(10)
            print(arr[0][0])
    finally:
        array_delete(arr)

Даночто поддержка Cython в C ++ ограничена и местами неудобна (и учитывая, что для ее использования в любом случае необходимо иметь достаточно хорошее понимание C ++), я думаю, что написание небольшого количества кода на C ++ обычно является разумным решением и может спасти довольнонемного времениНекоторые люди, кажется, хотят избежать этого любой ценой, хотя ....


Я бы по-прежнему рекомендовал использовать вектор векторов (vector<vector<double>>) вместо этого, поскольку вы получаете управление памятью бесплатно.Еще лучше было бы придерживаться типов Python и использовать список пустых массивов, но это может не подойти, если вы хотите взаимодействовать с внешним кодом C ++.

...