admin管理员组

文章数量:1390571

I have this structure in C:

MAX_NUMBER_OF_ITEMS = 9

typedef struct {   
   uint64_t status;    
   uint8_t serial_number_of_items [MAX_NUMBER_OF_ITEMS];   
   uint8_t version;
} Items_Info_t;

How can I convert it to Python, specifically the part:

uint8_t number_of_items [MAX_NUMBER_OF_ITEMS]

I try to do this way:

class SensorInfo:
    status: int
    serial_number_of_items: List[int] 
    version: int

Also, how can I perform serialization using struct.pack after that?

I have this structure in C:

MAX_NUMBER_OF_ITEMS = 9

typedef struct {   
   uint64_t status;    
   uint8_t serial_number_of_items [MAX_NUMBER_OF_ITEMS];   
   uint8_t version;
} Items_Info_t;

How can I convert it to Python, specifically the part:

uint8_t number_of_items [MAX_NUMBER_OF_ITEMS]

I try to do this way:

class SensorInfo:
    status: int
    serial_number_of_items: List[int] 
    version: int

Also, how can I perform serialization using struct.pack after that?

Share Improve this question edited Mar 14 at 7:56 mkrieger1 23.5k7 gold badges64 silver badges82 bronze badges asked Mar 14 at 4:13 user29971104user29971104 231 silver badge3 bronze badges 1
  • Is there something wrong with the Python class you have shown? It should do the job (assuming you also add the dataclass decorator). – mkrieger1 Commented Mar 14 at 7:57
Add a comment  | 

1 Answer 1

Reset to default 2

Create a class to encapsulate Items_Info_t and manage its serialization/deserialization.

  • The __init__ method initializes the object's attributes, after doing data validation to ensure that the input values are within the expected ranges.
  • Added an endian parameter to both the serialize and deserialize methods. The default value is '<' (little-endian).
  • Serialization with struct.pack:
    • '<': Representes the endianness ('<' for little-endian, '>' for big-endian, '!' for network byte order).
    • 'Q': Represents an unsigned 64-bit integer.
    • 'B' * MAX_NUMBER_OF_ITEMS: Represents MAX_NUMBER_OF_ITEMS unsigned 8-bit integers.
    • 'B': Represents a single unsigned 8-bit integer.
import struct
from typing import List


MAX_NUMBER_OF_ITEMS = 9

class ItemsInfo:
    def __init__(self, status: int, serial_number_of_items: List[int], version: int):
        if len(serial_number_of_items) != MAX_NUMBER_OF_ITEMS:
            raise ValueError(f"serial_number_of_items must have {MAX_NUMBER_OF_ITEMS} elements")

        if not all(0 <= item <= 255 for item in serial_number_of_items):
            raise ValueError("All serial numbers must be within the range 0-255 (uint8).")

        if not (0 <= version <= 255):
          raise ValueError("version must be within the range 0-255 (uint8).")

        if status < 0:
            raise ValueError("Status must be a non-negative integer (uint64).")

        self.status = status
        self.serial_number_of_items = serial_number_of_items
        self.version = version


    def serialize(self, endian: str = '<') -> bytes:
        if endian not in ('<', '>', '!'):
            raise ValueError("Endian must be '<' (little-endian), '>' (big-endian), or '!' (network byte order).")

        format_string = f"{endian}Q{'B' * MAX_NUMBER_OF_ITEMS}B"
        return struct.pack(format_string, self.status, *self.serial_number_of_items, self.version)


    @staticmethod
    def deserialize(data: bytes, endian: str = '<') -> 'ItemsInfo':
        if endian not in ('<', '>', '!'):
            raise ValueError("Endian must be '<' (little-endian), '>' (big-endian), or '!' (network byte order).")

        format_string = f"{endian}Q{'B' * MAX_NUMBER_OF_ITEMS}B"
        expected_size = struct.calcsize(format_string)

        if len(data) != expected_size:
            raise ValueError(f"Data length is incorrect. Expected {expected_size} bytes, got {len(data)}.")

        unpacked_data = struct.unpack(format_string, data)
        status = unpacked_data[0]
        serial_numbers = list(unpacked_data[1:1 + MAX_NUMBER_OF_ITEMS])
        version = unpacked_data[-1]
        return ItemsInfo(status, serial_numbers, version)

Testing

serial_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
items_info = ItemsInfo(status=1055, serial_number_of_items=serial_numbers, version=23)

serialized_data_network = items_info.serialize(endian='!')
print("Serialized Data (network byte order):", serialized_data_network)

print("\nDeserialized Data (network byte order):")
deserialized_info_network = ItemsInfo.deserialize(serialized_data_network, endian='!')
print("Status:", deserialized_info_network.status)
print("Serial Numbers:", deserialized_info_network.serial_number_of_items)
print("Version:", deserialized_info_network.version)

Output

Serialized Data (network byte order): b'\x00\x00\x00\x00\x00\x00\x04\x1f\x01\x02\x03\x04\x05\x06\x07\x08\t\x17'

Deserialized Data (network byte order):
Status: 1055
Serial Numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Version: 23

本文标签: How to transfer this part of code from C to Python using dataclassStack Overflow