Преобразование массива c_byte в разные типы - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь преобразовать массив c_byte в разные типы данных в Python, например, преобразование массива c_byte из восьми записей в int64 или double.

В моем проекте я прочитал длинный массив c_byte (n> 500), содержащий несколько значений датчиков с разными типами данных. Так что, возможно, первая запись - это bool, вторая и третья запись представляют собой int8, а записи 4-11 хранят двойное число. Я ищу удобный способ приведения этих записей массива в требуемые типы данных.

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

def convert_byte_to_binary(array):
    binary = ''
    for i in array:
        binary += format(i, '#010b')[2:]

    return binary

def convert_binary_to_uint(binary):
    return int(binary, 2)


array = read_cbyte_array(address, length)  # reads an array of size length, starting at address
array
[15, 30, 110, 7, 65]

convert_byte_to_binary(array)
'0000111100011110011011100000011101000001'

Я нашел библиотеку цепочек битов, которая делает нечто очень похожее на то, что я хочу. К сожалению, я не нашел поддержки для 64-битных целых или двойных чисел.

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

1 Ответ

0 голосов
/ 04 мая 2019

Для этого предназначена библиотека struct .

Вот краткий пример.Значение '<?2b8d' представляет:

  • < little-endian
  • ? bool
  • 2b два однобайтовых со знаком int.
  • 8d восемь двойных.

import ctypes
import struct

# Build the raw data
org_data = struct.pack('<?2b8d',True,-1,2,1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8)
print(org_data)

# Just to demo using a c_byte array...
byte_data = (ctypes.c_byte * len(org_data))(*org_data)
print(byte_data)

# convert to the original data
data = struct.unpack('<?2b8d',byte_data)
print(data)

Выход:

b'\x01\xff\x02\x9a\x99\x99\x99\x99\x99\xf1?\x9a\x99\x99\x99\x99\x99\x01@ffffff\n@\x9a\x99\x99\x99\x99\x99\x11@\x00\x00\x00\x00\x00\x00\x16@ffffff\x1a@\xcd\xcc\xcc\xcc\xcc\xcc\x1e@\x9a\x99\x99\x99\x99\x99!@'
<__main__.c_byte_Array_67 object at 0x0000025D4066B0C8>
(True, -1, 2, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8)
...