Как передать указатель на массив в Python для обернутой функции C++

StackOverflow https://stackoverflow.com/questions/940132

Вопрос

Я новичок в программировании на смешанном языке C++/Python и не имею особого представления об API Python/C.Я только начал использовать Boost.Python для создания библиотеки C++ для Python.Я застрял в обертке функции, которая принимает указатель на массив в качестве аргумента.Следующий (2-й сектор) представляет собой его прототип на C++.

class AAF{
  AAF(AAF_TYPE t);
  AAF(double v0, const double * t1, const unsigned * t2, unsigned T);
  ~AAF();
}

Правильно ли я делаю, обертывая это вот так в boost::python?

class_<AAF>("AAF", init<AAF_TYPE>())
  .def(init<double, const double*, const unsigned*, unsigned>());

Обратите внимание, что он успешно скомпилировался и скомпоновался, но я не мог понять, как его вызвать в Python.Мои наивные попытки, подобные приведенным ниже, не увенчались успехом.

>>> z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, [4, 5.5, 10], [1, 1, 2], 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, list, list, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

>>> t1 = array.array('d', [4, 5.5, 10])
>>> t2 = array.array('I', [1, 1, 2])
>>> z = AAF(10, t1, t2, 3);

Traceback (most recent call last):
  File "./test_interval.py", line 40, in <module>
    z = AAF(10, t1, t2, 3);
Boost.Python.ArgumentError: Python argument types in
    AAF.__init__(AAF, int, array.array, array.array, int)
did not match C++ signature:
    __init__(_object*, AAF_TYPE)
    __init__(_object*, double, double const*, unsigned int const*, unsigned int)

Мой второй вопрос: нужно ли мне также обертывать деструктор?Пожалуйста, укажите, может ли это быть необходимо в некоторых случаях, но не всегда.

Это было полезно?

Решение

Упаковка правильная (в принципе), но в

AAF(10, [4, 5.5, 10], [1, 1, 2], 3);

(как указывает интерпретатор), вы передаете в свою функцию объекты списка Python, а не указатели.

Короче говоря, если вашей функции нужно работать только со списками Python, вам нужно изменить свой код, чтобы использовать этот интерфейс (вместо использования указателей).Если вам нужно сохранить этот интерфейс, вам нужно написать функцию-оболочку, которая берет список из Python, выполняет правильное преобразование и вызывает вашу исходную функцию C++.То же самое относится и к массивам numpy.

Обратите внимание, что boost::python предлагает некоторый встроенный механизм для преобразования контейнеров Python в контейнеры, совместимые с stl.

Примером кода упаковки для вашего случая может быть

void f(list o) {
    std::size_t n = len(o);
    double* tmp = new double[n];
    for (int i = 0; i < n; i++) {
        tmp[i] = extract<double>(o[i]);
    }
    std::cout << std::endl;
    // use tmp
    delete tmp;
}

Пожалуйста, ознакомьтесь с руководством по boost.python по адресу http://www.boost.org/doc/libs/1_39_0/libs/python/doc/tutorial/doc/html/index.html.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top