Использование ctypes Python для получения буфера чисел с плавающей запятой из общей библиотеки в строку Python

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

Вопрос

Я пытаюсь использовать ctypes Python для использования этих двух функций 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 сработал.

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

Решение

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

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)
То же, что и стандартная библиотечная функция memmove C:копии count байты из src к dst. dst и src должны быть целыми числами или экземплярами ctypes, которые можно преобразовать в указатели.

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

Другие советы

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

c_float_p = ctypes.POINTER(ctypes.c_float)

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

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