Использование Python ctypes, чтобы получить буфер с плавающей точкой из разделяемой библиотеки в строку Python - PullRequest
2 голосов
/ 01 апреля 2009

Я пытаюсь использовать Python ctypes для использования этих двух функций C из общей библиотеки:

bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()

Первая функция работает нормально. Я могу сказать это, поместив некоторый код отладки в общую библиотеку и проверив ввод.

Проблема заключается в получении данных. RGB-буфер - это указатель на число с плавающей точкой (очевидно), и этот указатель остается постоянным в течение всего жизненного цикла приложения. Поэтому, когда я хочу распаковать изображение, я звоню decompress_rgb, а затем мне нужно посмотреть, что находится в месте, указанном getRgbBuffer. Я знаю, что размер буфера (720 * 288 * sizeof (float)), поэтому я думаю, что это должно где-то вступить в игру.

Типа c_float_p нет, поэтому я решил попробовать:

getRgbBuffer.restype = c_char_p

Тогда я делаю:

ptr = getRgbBuffer()
print "ptr is ", ptr

, который просто выводит:

ptr = 3078746120

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

Как я могу получить содержимое всего буфера в строку Python?

Редактировать: Пришлось изменить:

getRgbBuffer.restype = c_char_p

до

getRgbBuffer.restype = c_void_p

но тогда ответ BastardSaint сработал.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2009

Не полностью протестировано, но я думаю, что-то вроде этого:

buffer_size = 720 * 288 * ctypes.sizeof(ctypes.c_float)
rgb_buffer = ctypes.create_string_buffer(buffer_size) 
ctypes.memmove(rgb_buffer, getRgbBuffer(), buffer_size)

Клавиша - это функция ctypes.memmove(). Из документации ctypes :

memmove(dst, src, count)
То же, что и стандартная функция библиотеки C memmove: копирует count байтов из src в dst. dst и src должны быть экземплярами целых чисел или типов, которые можно преобразовать в указатели.

После запуска приведенного выше фрагмента, rgb_buffer.value вернет содержимое до первого '\0'. Чтобы получить все байты в виде строки Python, вы можете нарезать целое: buffer_contents = rgb_buffer[:].

2 голосов
/ 01 апреля 2009

Прошло много времени с тех пор, как я использовал ctypes, и у меня нет чего-то, что возвращает «double *», достаточно удобный для проверки этого, но если вы хотите c_float_p:

c_float_p = ctypes.POINTER(ctypes.c_float)

Читая ответ BastardSaint, вы просто хотите получить необработанные данные, но я не был уверен, что вы делаете это как обходной путь к отсутствию c_float_p.

...