• 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)))
  • 相关阅读:
    Aix_bugzilla
    aix Mysql安装 Oracle官方教程
    Aix6.1安装openssh
    日媒:阿里巴巴上市融资或超Facebook
    设计模式(一)---单例模式
    Handler具体解释系列(七)——Activity.runOnUiThread()方法具体解释
    TCP/IP协议族——IP工作原理及实例具体解释(上)
    leetCode 41.First Missing Positive (第一个丢失的正数) 解题思路和方法
    Material Design之RecyclerView的使用(一)
    jQuery和CSS3超酷表单美化插件
  • 原文地址:https://www.cnblogs.com/luke0011/p/9183729.html
Copyright © 2020-2023  润新知