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 ++ в библиотеке, которая вызывает this, отправляет указатель на массив «const uint_16» s, поэтому я определил const_ushort таким образом, потому что в противном случае типы не объединяются. Я никак не могу изменить библиотеку.

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

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

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

10
задан Josiah 12 March 2011 в 06:29
поделиться