海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库

本文介绍了sbc库,这是一个用于在Python中进行C语言格式结构体和二进制转换的工具。sbc支持ctypes的所有类型,并提供了结构体到二进制及二进制到结构体的转换方法。文章通过示例展示了如何定义和使用不同对齐方式的结构体,并进行了编码和解码操作。此外,还提供了项目的GitHub和Gitee链接,以及详细的Python和C类型对应表。

海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

在线文档地址

介绍

sbc: struct convert binary.C语言格式结构体和二进制转换库.

本软件包已上传到pypi,可输入命令直接安装:

pip install sbc

开源

Python和C对应类型

本软件包封装了ctypes,支持cytpes所有类型,对应表如下:

cyteps typeCtypePython type
c_bool_Boolbool (1)
c_charchar1-character bytes object
c_wcharwchar_t1-character string
c_bytecharint
c_ubyteunsigned charint
c_shortshortint
c_ushortunsignedshort int
c_intintint
c_uintunsigned intint
c_longlongint
c_ulongunsigned longint
c_longlong__int64 or long longint
c_ulonglongunsigned __int64 or unsigned long longint
c_size_tsize_tint
c_ssize_tssize_t or Py_ssize_tint
c_floatfloatfloat
c_doubledoublefloat
c_longdoublelong doublefloat
c_char_pchar * (NUL terminated)bytes object or None
c_wchar_pwchar_t * (NUL terminated)string or None
c_void_pvoid *int or None

使用说明

软件包支持4种C语言结构:

类名说明
LEFormat1字节对齐的小端结构体
LEFormatAlign44字节对齐的小端结构体
LEFormatAlign88字节对齐的小端结构体
BEFormat1字节对齐的大端结构体
BEFormatAlign44字节对齐的大端结构体
BEFormatAlign84字节对齐的大端结构体

定义C语言结构体需继承对应的结构体,然后在_fields_中定义对应的成员。示例:

class TStruct1(sbc.LEFormat):
    _fields_ = [
        # (字段名, c类型)
        ('a', sbc.c_uint32),
        ('b', sbc.c_int16),
        ('c', sbc.c_uint8),
    ]

C结构体转换为二进制字节流使用方法encode,二进制字节流转换为C语言结构体使用方法decode.API:

"""
C语言格式结构体转换成二进制
:return: 返回二进制字节流
"""
def struct_to_bytearray(self) -> bytearray

"""
二进制转换成C语言结构体
:return: 返回True表示转换成功,False表示转换失败
"""
def bytearray_to_struct(self, data: bytearray) -> bool

"""
读取结构体字节数
"""
def size(self) -> int

示例

import sbc

import unittest


class TStruct1(sbc.LEFormat):
    _fields_ = [
        # (字段名, c类型)
        ('a', sbc.c_uint32),
        ('b', sbc.c_int16),
        ('c', sbc.c_uint8),
    ]


class TStruct2(sbc.LEFormatAlign4):
    _fields_ = [
        # (字段名, c类型)
        ('a', sbc.c_uint32),
        ('b', sbc.c_int16),
        ('c', sbc.c_uint8),
    ]


class TStruct3(sbc.BEFormat):
    _fields_ = [
        # (字段名, c类型)
        ('a', sbc.c_uint16),
        ('b', sbc.c_uint8 * 5),
        ('c', sbc.c_uint32),
    ]


class _UnitTest(unittest.TestCase):
    def test_case1(self):
        """
        测试小端1字节对齐,C语言结构体转换为二进制
        """
        ts = TStruct1()
        ts.a = 0x12345678
        ts.b = 0x2345
        ts.c = 0x67
        data = ts.struct_to_bytearray()
        self.assertEqual(len(data), 7)
        self.assertEqual(data, bytearray([0x78, 0x56, 0x34, 0x12, 0x45, 0x23, 0x67]))

    def test_case2(self):
        """
        测试小端1字节对齐,二进制转换为C语言结构体
        """
        ts = TStruct1()
        ts.bytearray_to_struct(bytearray([0x78, 0x56, 0x34, 0x12, 0x45, 0x23, 0x67]))
        self.assertEqual(ts.a, 0x12345678)
        self.assertEqual(ts.b, 0x2345)
        self.assertEqual(ts.c, 0x67)

    def test_case3(self):
        """
        测试小端4字节对齐,C语言结构体转换为二进制
        """
        ts = TStruct2()
        ts.a = 0x12345678
        ts.b = 0x2345
        ts.c = 0x67
        data = ts.struct_to_bytearray()
        self.assertEqual(len(data), 8)
        self.assertEqual(data, bytearray([0x78, 0x56, 0x34, 0x12, 0x45, 0x23, 0x67, 0x00]))

    def test_case4(self):
        """
        测试小端4字节对齐,二进制转换为C语言结构体
        """
        ts = TStruct2()
        ts.bytearray_to_struct(bytearray([0x78, 0x56, 0x34, 0x12, 0x45, 0x23, 0x67, 0x00]))
        self.assertEqual(ts.a, 0x12345678)
        self.assertEqual(ts.b, 0x2345)
        self.assertEqual(ts.c, 0x67)

    def test_case5(self):
        """
        测试小端4字节对齐,二进制转换为C语言结构体
        """
        ts = TStruct2()
        err = ts.bytearray_to_struct(bytearray([0x78, 0x56, 0x34]))
        self.assertEqual(err, False)

    def test_case6(self):
        """
        测试大端1字节对齐,C语言结构体转换为二进制
        """
        ts = TStruct3()
        ts.a = 0x2345
        for i in range(5):
            ts.b[i] = i
        ts.c = 0x12345678
        data = ts.struct_to_bytearray()
        self.assertEqual(len(data), 11)
        self.assertEqual(data, bytearray([0x23, 0x45, 0x00, 0x01, 0x02, 0x03, 0x04, 0x12, 0x34, 0x56, 0x78]))


def print_hex(data):
    for i in data:
        print('%x' % i, end=' ')
    print()


if __name__ == '__main__':
    suite = unittest.TestSuite()
    runner = unittest.TextTestRunner()
    runner.run(suite)

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值