python中将多个参数打包为字节流的第二种方法

该方法使用ctypes模块中的memmove函数将结构体数据对应的内存移动到缓冲区对应的位置,完成打包过程,相比上种方法较为麻烦。

代码如下:

  1 # -*- coding: utf-8 -*-#
  2 
  3 #-------------------------------------------------------------------------------
  4 # Name:         以结构体形式直接打包参数包
  5 # Description:  整个包大小为64Byte,包头为0X”FAA5 FBB5 FCC4 FDD5”,包尾为0X”5FA5 5FB5 5FC5 5FD5 ”,中间不足部分补0
  6 #               发送的参数定义(有符号整型数字)
  7 #               cmdType = 1         # 1 Byte
  8 #               sigType = 2         # 1 Byte
  9 #               startFreq = 40      # 4 Byte
 10 #               stopFreq = 400      # 4 Byte
 11 #               deltFreq = 10       # 4 Byte
 12 #               pulseNum = 37       # 2 Byte
 13 #               pulseWidth = 0      # 4 Byte
 14 #               PRF = 25000000      # 4 Byte
 15 #               receiverFreq = 1000 # 4 Byte
 16 # Author:       lgk
 17 # Date:         2018/6/14
 18 #-------------------------------------------------------------------------------
 19 
 20 import struct
 21 import ctypes
 22 import binascii
 23 import re
 24 
 25 #字节顺序定义
 26 byteOrders = {'Native order':'@',
 27               'Native standard':'=',
 28               'Little-endian':'<',
 29               'Big-endian':'>',
 30               'Network order':'!'}
 31 
 32 byteOrder = 'Little-endian'
 33 
 34 fmt_head = fmt_tail = struct.Struct(byteOrders[byteOrder] + "8B")
 35 fmt_body = struct.Struct(byteOrders[byteOrder] + "2b3i1h3i")
 36 bufferLength = 64
 37 
 38 def getSendInfo(info):
 39     p = re.compile('.{1,2}') #匹配任意字符1-2次
 40     t = ' '.join(p.findall(info.upper()))
 41     return t
 42 
 43 #定义本地形式结构体
 44 class CMDParaNative(ctypes.Structure):
 45     _pack_ = 1
 46     _fields_ = [
 47         ('cmdType', ctypes.c_int8),
 48         ('sigType', ctypes.c_int8),
 49         ('startFreq', ctypes.c_int32),
 50         ('stopFreq', ctypes.c_int32),
 51         ('deltFreq', ctypes.c_int32),
 52         ('pulseNum', ctypes.c_int16),
 53         ('pulseWidth', ctypes.c_int32),
 54         ('PRF', ctypes.c_int32),
 55         ('receiverFreq', ctypes.c_int32)
 56     ]
 57 
 58 #定义大端形式结构体
 59 class CMDParaBigEndian(ctypes.BigEndianStructure):
 60     _pack_ = 1
 61     _fields_ = [
 62         ('cmdType', ctypes.c_int8),
 63         ('sigType', ctypes.c_int8),
 64         ('startFreq', ctypes.c_int32),
 65         ('stopFreq', ctypes.c_int32),
 66         ('deltFreq', ctypes.c_int32),
 67         ('pulseNum', ctypes.c_int16),
 68         ('pulseWidth', ctypes.c_int32),
 69         ('PRF', ctypes.c_int32),
 70         ('receiverFreq', ctypes.c_int32)
 71     ]
 72 
 73 #定义小端形式结构体
 74 class CMDParaLittleEndian(ctypes.LittleEndianStructure):
 75     _pack_ = 1
 76     _fields_ = [
 77         ('cmdType', ctypes.c_int8),
 78         ('sigType', ctypes.c_int8),
 79         ('startFreq', ctypes.c_int32),
 80         ('stopFreq', ctypes.c_int32),
 81         ('deltFreq', ctypes.c_int32),
 82         ('pulseNum', ctypes.c_int16),
 83         ('pulseWidth', ctypes.c_int32),
 84         ('PRF', ctypes.c_int32),
 85         ('receiverFreq', ctypes.c_int32)
 86     ]
 87 
 88 if byteOrder == 'Little-endian':
 89     para = CMDParaLittleEndian(1, 2, 40, 400, 10, 37, 0, 25000000, 1000)
 90 elif byteOrder == 'Big-endian':
 91     para = CMDParaBigEndian(1, 2, 40, 400, 10, 37, 0, 25000000, 1000)
 92 else:
 93     para = CMDParaNative(1, 2, 40, 400, 10, 37, 0, 25000000, 1000)
 94 
 95 headInfo = [0xFA, 0xA5, 0xFB, 0xB5, 0xFC, 0xC5, 0xFD, 0xD5]
 96 tailInfo = [0x5F, 0xA5, 0x5F, 0xB5, 0x5F, 0xC5, 0x5F, 0xD5]
 97 
 98 sendBuffer = ctypes.create_string_buffer(bufferLength) #创建发送缓冲区
 99 
100 #将待发送的参数打包到缓冲区
101 fmt_head.pack_into(sendBuffer, 0, *headInfo)
102 fmt_tail.pack_into(sendBuffer, bufferLength-fmt_tail.size, *tailInfo)
103 #将结构体数据对应的内存移动到缓冲区对应的位置
104 ctypes.memmove(ctypes.addressof(sendBuffer)+fmt_head.size, ctypes.byref(para), ctypes.sizeof(para))
105 # ctypes.memmove(ctypes.byref(sendBuffer, fmt_head.size), ctypes.byref(para), ctypes.sizeof(para)) #与上面一行等价
106 
107 #打印出字节流的16进制信息(byteOrder = 'Little-endian')
108 #FA A5 FB B5 FC C5 FD D5 01 02 28 00 00 00 90 01 00 00 0A 00 00 00 25 00 00 00 00 00 40 78 7D 01 E8 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5F A5 5F B5 5F C5 5F D5
109 print(getSendInfo(binascii.hexlify(sendBuffer)))

 

posted on 2018-06-14 16:38  lgk  阅读(531)  评论(1编辑  收藏  举报

导航