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.

  • OverflowError возникает при использовании cython с большим int
  • Неопределенный импорт символьной копии модуля Cython
  • Проблема с Python / Cython при импорте файлов и методов
  • Cython: преобразовать представление памяти в массив NumPy
  • Распространение общей библиотеки и некоторых C-кода с помощью модуля расширения Cython
  • Могу ли я использовать этот параллельный шаблон итератора с Cython?
  • Cython не будет компилироваться на Windows 7 x64
  • Организация проекта с Cython и C ++
  • Опции для кинематографического кода Cython
  • Оптимизация numpy.dot с Cython
  • Учебники по оптимизации нетривиальных приложений Python с расширениями C или Cython
  •  
    Interesting Posts for Van-Lav

    Тестирование модуля Python CLI

    Переименуйте раздел config.ini с помощью ConfigParser в python

    Как отсортировать словарь Python по значению?

    Есть ли более быстрый способ проверить, имеют ли два списка те же самые элементы, что и Pythons, встроенные в оператор?

    Проблема при вычислении контрольной суммы: литье int в подписанный int32

    Получить ненулевые элементы в pandas DataFrame

    Правило зависимости пыталось заглушить первичный ключ в SQLAlchemy, когда ограничение внешнего ключа является частью составного первичного ключа

    Python PIL: как сделать область прозрачной в PNG?

    Python запрашивает модуль GET / POST + различные запросы клиентов REST, занимающих больше времени, чем завиток

    Как я могу обойти эту проблему, создавая виртуальную среду с помощью Python с настраиваемой компоновкой?

    Как я могу показать цифры отдельно в matplotlib?

    Как запустить скрипт Python в фоновом режиме даже после выхода из системы SSH?

    Многопоточность в python

    Являются ли встроенные функции плотности вероятности `scipy.stat.distributions` медленнее, чем пользователь предоставил один?

    Как суммировать первое значение в каждом кортеже в списке кортежей в Python?

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