Cython – преобразование указателей на массивы в объекты Python

Хорошо, я так близок к тому, чтобы закончить это, я могу попробовать его. За последние несколько недель я пытался создать расширение Python для взаимодействия с библиотекой, написанной на C ++ через Cython. Немного помогая ребятам здесь и пару друзей, мне удалось получить то, что похоже на 98% пути. Остается только одно: я не могу для жизни понять, как превратить указатель на массив беззнаковых шорт в объект python (предпочтительно список).

Немного фона, я пытаюсь взаимодействовать с частью библиотеки, которая устанавливает функцию обратного вызова, которую я успешно сделал с этим:

global callbackfunc ctypedef unsigned short const_ushort "const uint16_t" ctypedef void (*Function1)(const_ushort *data, unsigned width, unsigned height) cdef extern from "lib.hpp": void SetCallback(Function1) cdef void cSetCallback(Function1 function): SetCallback(function) cdef void callcallback(const_ushort *data, unsigned width, unsigned height): global callbackfunc callbackfunc(data,width,height) cSetCallback(callcallback) def PySetCallback(callbackFunc): global callbackfunc callbackfunc = callbackFunc 

Проблема возникает в функции «callcallback», где я получаю сообщение об ошибке: «Невозможно преобразовать const_ushort * в объект Python». Моя первая попытка – создать новый список python и выполнить цикл, чтобы каждый элемент массива попал в список python, например:

 datalist = [] for i in range(width*height): datalist += data[i] 

Что, к сожалению, связывает меня с скомпилированным кодом на языке cython, пытаясь определить тип как «const const unsigned short», что, очевидно, является проблемой.

Затем я попробовал это:

 datalist = [] for i in data: datalist += i 

Что дает мне «Итерация массива C требует известного конечного индекса». Заметьте, что я знаю очень мало C / C ++, поэтому большинство из них для меня не имеет большого смысла.

Так или иначе, есть ли какой-либо эффективный способ перевода такого указателя в объект python (желательно быстрее, чем цикл через массив, поскольку обычно это около 57344 элемента, и это довольно чувствительно для времени)

Изменить : немного больше разъяснений, как я уже упоминал, я работаю с обратными вызовами, а функция C ++ в библиотеке, которая вызывает это, отправляет указатель на массив «const uint_16», поэтому я определил const_ushort таким образом, потому что иначе типы не объединяются. Я никак не могу изменить библиотеку.

Edit2 : Похоже, я понял. То, что мне в итоге пришлось сделать, было явно отброшено массивом как массив беззнаковых шорт, а не массив const unsigned shorts, чтобы я мог индексировать их с константой. Для этого я создал еще одну функцию C ++, подобную этой (кто-то другой написал ее для меня, я почти не знаю C ++):

 unsigned short *convert_short(const unsigned short *test){ return const_cast<unsigned short *>(test); } 

и это позволило мне создать функцию « getindex » в моем классе и вернуть правильные значения на основе функции. Так что да, Python, кажется, правильно читает массивы и еще много чего, поэтому этот случай кажется закрытым. Большое спасибо.

2 Solutions collect form web for “Cython – преобразование указателей на массивы в объекты Python”

 ctypedef unsigned short const_ushort "const uint16_t" 

делает const в коде C, поэтому вы получаете typedef unsigned short const uint16_t в котором const имеет смысла. (Он также переопределяет стандартный тип uint16_t , который он не должен.)

У вас может быть больше успеха с

 ctypedef unsigned short *ushort_p "ushort_p" 

По какой-то причине Cython, похоже, не распознает ключевое слово C const . Возможно, вам придется использовать обертку вокруг ваших обратных вызовов, чтобы справиться с проблемой const .

Если вы хотите, чтобы указатель переводился в объект Python, оберните его в cdef class . Убедитесь, что класс записывает высоту и ширину, поскольку они не записываются с массивом C.

Это не совсем то, что вы просите, но если вы хотите сделать, это работать с массивом unsigned shorts в Cython, а затем сделать ваш ответ доступным на стороне Python, вы можете создать Numpy ndarray на стороне Python и пройти он в Cython, где он примерно такой же, как многомерный массив. Таким образом, вы получаете управление памятью Python, некоторый удобный синтаксис индексирования и скорость работы с реальным массивом в Cython.

Вот пример из моих решений Project Euler.

  • Проверка для nan в Cython
  • Cython компилируется в exe, Windows
  • Каков самый простой способ сделать дополнительное расширение C для пакета python?
  • Cython и fortran - как скомпилировать без f2py
  • утечка памяти, вызывающая функцию cython с большими параметрами массива numpy?
  • Сравнение производительности Fortran, Numpy, Cython и Numexpr
  • Скомпилируйте основную программу Python с помощью Cython
  • Как правильно передать scipy.sparse CSR-матрицу в функцию cython?
  •  
    Interesting Posts for Van-Lav

    Как различать метод и функцию в декораторе?

    Выдача «нечетких» переводов на django-страницах?

    Способы избежать ошибок MySQLdb «Команды не синхронизированы; вы не можете запустить эту команду сейчас »(2014) исключение

    Boost.Python вызывает по ссылке: TypeError: нет конвертера to_python (по значению) для типа C ++:

    Python: лучший способ добавить к sys.path относительно текущего скрипта

    mutagen: как обнаружить и внедрить обложку альбомов в mp3, flac и mp4

    Python: возможно ли получить доступ к возвращаемому значению внутри предложения `finally`?

    Что такое pythonic способ установить переменные класса?

    DatabaseSessionIsOver с Pony ORM из-за ленивой загрузки?

    Как использовать python для запуска интерактивной программы оболочки?

    Рекурсия Python max, вопрос о sys.setrecursionlimit ()

    Как заставить ваш персонаж двигаться, не нажимая несколько раз на кнопки?

    Создайте экземпляр из сериализатора, не сохраняя его в db

    Как читать и хранить значения из текстового файла в словаре.

    Скорость работы оператора Python

    Python - лучший язык программирования в мире.