2015-03-15 2 views
1

У меня есть блок памяти с двоичными данными. Блок был создан с помощью ctypes.create_string_buffer, поэтому данные изменяемы и доступны в виде массива.Python initialise Struct

Каждые 32 бита состоят из пары, 20-битного целых без знака и 12-разрядного целого числа без знака.

Я хочу получить доступ к паре n-го элемента и изменить значения в блоке памяти.

У меня есть структура:

from ctypes import * 
class Int(Structure): 
    _fields_ = [("first", c_uint, 20), 
       ("second", c_uint, 12)] 

Как заселить Структуру из моих данных? Есть ли похожий указатель на C, который я могу установить, чтобы указать структуру по моим данным?

ответ

2

Вы можете создать тип массива вашего Int, умножив тип вашей структуры на его длину; здесь я использую 5 в качестве примера, вы можете использовать любую длину вам нужно:

IntArray5 = Int * 5 
arr = IntArray5() 

Если вам нужно использовать различные длины каждый раз, нет никакой необходимости назвать тип, вы можете просто использовать:

arr = (Int * 5)() 

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

myfunc = libfoo.myfunc 
myfunc(arr, len(arr)) 

Теперь вы должны быть в состоянии получить доступ к элементам из arr:

print arr[0].first 
print arr[0].second 

Однако, если по каким-то причинам вы не можете передать этот массив в функцию непосредственно, а вместо этого нужно взять существующий буфер строки и производят массив Int, который разделяет буфер, вы можете использовать from_buffer в eryksun предлагает:

arr = (Int * 5).from_buffer(buff) 

Или, если вы хотите скопировать в новый массив, а не разделяя основной буфер:

arr = (Int * 5).from_buffer_copy(buff) 
+0

@eryksun Да, вы правы, эта часть была неясной. Я попытался немного разъяснить в редактировании. –

+0

Две концепции, которые я отсутствовал, были (Int * 5) и from_buffer. Он работает, спасибо. –

Смежные вопросы