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)))

 

转载于:https://www.cnblogs.com/luke0011/p/9183729.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文件的方法有很多种,下面介绍一种常用的方法: 1. 安装PyInstaller 打开命令行工具(如cmd或PowerShell),输入以下命令安装PyInstaller: ``` pip install pyinstaller ``` 2. 编写打包脚本 在项目的根目录下创建一个名为build.py的Python脚本,用于打包程序。示例代码如下: ```python import os import sys import subprocess def main(): # 获取当前脚本所在目录 base_dir = os.path.dirname(os.path.abspath(__file__)) # 执行打包命令 cmd = [ 'pyinstaller', '--clean', '--onefile', '--windowed', '--icon={}/icon.ico'.format(base_dir), # 替换为自己的图标文件路径 'main.py' # 替换为程序的入口文件名 ] subprocess.call(cmd) if __name__ == '__main__': main() ``` 该脚本使用了subprocess模块来执行打包命令。打包命令中的参数说明: - --clean:清除之前的打包结果 - --onefile:打包成单个exe文件 - --windowed:不显示命令行窗口,只显示GUI界面 - --icon:指定程序的图标文件路径 - main.py:程序的入口文件名,替换为自己的入口文件名 3. 执行打包脚本 在命令行中执行以下命令,执行打包脚本: ``` python build.py ``` 执行完成后,在项目目录下会生成一个dist目录,其中包含了打包生成的exe文件和其他依赖文件。 注意事项: - 如果程序依赖了第三方库,需要在打包前先使用pip安装这些库。 - 打包时需要保证程序能够正常运行,否则可能会导致打包失败或打包结果无法正常运行。 - 打包结果可能会比源代码大很多,可以使用UPX等工具对exe文件进行压缩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值