Python与C++结构体交互
需求:根据接口规范,实现与服务端的数据交互
服务端结构体分包头、包体、包尾
包头C++结构体示例如下
typedef struct head
{
BYTE string1;
BYTE string2; //包类型
BYTE string3; //版本号,目前为0
char string4[];
int string5;
int string6;
unsigned int string7; //包头校验和,以上所有字段的crc32校验和
char string8;
char string9;
}protocol_head;
包体C++结构体示例如下
typedef struct body
{
char sessid[];
int datalen;
BYTE data[];
};
包尾C++结构体示例如下
// 包尾 - 粘包分割
typedef struct tag_protocol_tail
{
BYTE tail[]
}protocol_tail;
根据包头结构体的要求,需要使用CRC32校验
unsigned int GetCRC32(const unsigned char *pbData, int nSize)
{
unsigned long Table[]={};
unsigned long ulPolynomial = 0xEDB88320; unsigned long dwCrc;
int i,j;
for(i = ; i < ; i++)
{
dwCrc = i;
for(j = ; j > ; j--)
{
if(dwCrc & )
dwCrc = (dwCrc >> ) ^ ulPolynomial;
else
dwCrc >>= ;
}
Table[i] = dwCrc;
} unsigned long dwCrc32 = 0xFFFFFFFF;
int idx=;
while(nSize--)
{
dwCrc32 = ((dwCrc32) >> ) ^ Table[(pbData[idx]) ^ ((dwCrc32) & 0x000000FF)];
idx++;
}
return ~dw
python 实现内容
struct中支持的格式如下表:
Format |
C Type |
Python |
字节数 |
x |
pad byte |
no value |
1 |
c |
char |
string of length 1 |
1 |
b |
signed char |
integer |
1 |
B |
unsigned char |
integer |
1 |
? |
_Bool |
bool |
1 |
h |
short |
integer |
2 |
H |
unsigned short |
integer |
2 |
i |
int |
integer |
4 |
I |
unsigned int |
integer or long |
4 |
l |
long |
integer |
4 |
L |
unsigned long |
long |
4 |
q |
long long |
long |
8 |
Q |
unsigned long long |
long |
8 |
f |
float |
float |
4 |
d |
double |
float |
8 |
s |
char[] |
string |
1 |
p |
char[] |
string |
1 |
P |
void * |
long |
举例C中常用:
int16=short --> h
uint32=unsigned int --> I
UInt64=unsigned long long --> Q
byte表示一个字节,对应C的unsigned char --> B
python中CRC32校验
def mycrc32(szString):
# 校验码
m_pdwCrc32Table = [0 for x in range(0, 256)]
dwPolynomial = 0xEDB88320
dwCrc = 0
for i in range(0, 255):
dwCrc = i
for j in [8, 7, 6, 5, 4, 3, 2, 1]:
if dwCrc & 1:
dwCrc = (dwCrc >> 1) ^ dwPolynomial
else:
dwCrc >>= 1
m_pdwCrc32Table[i] = dwCrc
dwCrc32 = 0xFFFFFFFFL
for i in szString:
b = ord(i)
dwCrc32 = ((dwCrc32) >> 8) ^ m_pdwCrc32Table[(b) ^ ((dwCrc32) & 0x000000FF)]
dwCrc32 = dwCrc32 ^ 0xFFFFFFFFL
return dwCrc32
C++和python关于CRC32代码传入参数如何理解?
根据上面C++代码内容,可以看到传入2位参数,它的第一位参数是整个包头+包体+包尾内容,第二位参数是整个包前多少位的长度需要校验
对于python代码,实际上只要传入需要校验的内容。
本文中需要传入的内容实际上是包头的的前6个字段,也就是包头的string1+string2+string3+string4+string5+string6
包头代码
# 包头, data为传入的包体,body_len是包体长度
def qzj_head(data, body_len):
string1 = 100
string2 = 1
string3 = 0
string4 = ""
string5 = body_len
string6 = body_len string1 = struct.pack('B', string1 )
string2 = struct.pack('B', string2 )
string3 = struct.pack('B', string3)
string4 = struct.pack('33s', string4 )
string5 = struct.pack('i', string5 )
string6 = struct.pack('i', string6 ) string7_struct = string1+string2+string3+string4+string5+string6 # 前面的6个字段内容
string7_crc32 = des_key.mycrc32(headcrc_str) # crc32校验
string7 = struct.pack('I', string7_crc32)
string8 = 0
string9 = 0
string8 = struct.pack('B', string8)
string9 = struct.pack('B', string9) request_head = string1+string2+string3+string4+string5+string6+string7+string8+string9+data
return request_head
包尾代码
# 包尾,data是传入的包头+包体
def qzj_tail(data):
tail1 = '\0'
tail2 = '\0'
tail3 = '\r'
tail4 = '\n'
tail1 = struct.pack('s', tail1)
tail2 = struct.pack('s', tail2)
tail3 = struct.pack('s', tail3)
tail4 = struct.pack('s', tail4)
request_tail = data+tail1+tail2+tail3+tail4
return request_tail
包体代码
# 包体, data是要发送的json数据
def body_100(data):
string1 = ''
string2 = len(data)
string3 = data string1 = struct.pack('33s', string1)
string2 = struct.pack('i', string2)
string3 = struct.pack('%ds' % datalen_num, string3)
request_body = string1+string2+string3
return request_body, len(request_body)
Python与C++结构体交互的更多相关文章
- python与C结构体之间二进制数据转换
python与C结构体之间数据转换 前言 在实际应用中,可能会遇到直接和C进行二进制字节流协议通信,这时要把数据解包成python数据,如果可能,最好与C定义的结构体完全对应上. python中有2种 ...
- c++调用python系列(1): 结构体作为入参及返回结构体
最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...
- ctypes 操作 python 与 c++ dll 互传结构体指针
CMakeLists.txt # project(工程名) project(blog-3123958139-1) # add_library(链接库名称 SHARED 链接库代码) add_libra ...
- python 传递结构体指针到 c++ dll
CMakeLists.txt # project(工程名) project(xxx) # add_library(链接库名称 SHARED 链接库代码) add_library(xxx SHARED ...
- slots - Python的结构体 转
上个月看了篇文章 “SAVING 9 GB OF RAM WITH PYTHON’S __SLOTS__”,原来Python也有类似结构体的东东.拖了一个月才写这篇,是因为太久没看pyth ...
- python如何将指定路径下的某类型文件,返回一个树形结构体,让前端显示为树形的目录结构
最近遇到一个问题就是某个linux的目录下有各种文件现在的要求是只需要返回.kml格式的文件,并根据前端要求返回如下结构体即:[{'children': [{'children': [{'title' ...
- 『Python CoolBook』C扩展库_其四_结构体操作与Capsule
点击进入项目 一.Python生成C语言结构体 C语言中的结构体传给Python时会被封装为胶囊(Capsule), 我们想要一个如下结构体进行运算,则需要Python传入x.y两个浮点数, type ...
- python 实现结构体
# python 使用类创建结构体 class Myclass(object): class Struct(object): def __init__(self, name, age, job): s ...
- Python 定义及使用结构体
Python中没有专门定义结构体的方法,但可以使用class标记定义类来代替结构体,其成员可以在构造函数__init__中定义,具体方法如下. class seqNode: def __init__( ...
随机推荐
- C#利用iComparable接口实现List排序
List<T>类可以使用Sort()方法对元素排序. Sort()方法定义了几个重载方法,分别是 public void List<T>.Sort(),不带有任何参数的Sor ...
- 解决Eclipse项目图标上的红色感叹号,红叉
从外部导入了几个jar包发现工程上出现红叉,但展开又没有详细的指明任何错误,可能过如下几步: 1.检查Build Path中的各个依赖jar及library是否有warning的标志,若有,处理之: ...
- ubuntu14.04切换root用户
打开命令窗口(CTRL+ALT+T),输入:sudo -s -->接着输入管理密码, -->已经切换到root用户
- python 登陆接口
#!/usr/bin/env pythonimport sysname = ''pw=''name_num = 0pw_num = 0#black_list = []with open('a.txt' ...
- [转]Mybatis出现:无效的列类型: 1111 错误
原文地址:http://www.cnblogs.com/sdjnzqr/p/4304874.html 在使用Mybatis时,不同的xml配置文件,有的会提示:无效的列类型: 1111 比如这个sql ...
- java学习笔记--java中的基本数组[5]
java基础很重要, 今天呆家看java视频,顺便总结前几周看的java书籍,做一下简单的总结:1:数组的声明,2:数组的赋值: 3:数组的方法: 声明一个数组主要有两种方式: //类型 []数组名字 ...
- Leetcode 110. Balanced Binary Tree
Given a binary tree, determine if it is height-balanced. For this problem, a height-balanced binary ...
- Hadoop设置环境变量注意事项
路径是/etc/profile. 这个东西不能再普通下设置,打开是彩色的,即便是“:wq!”也不能保存,必须去root下,黑白的. 然后root下source /etc/profile,然后exit, ...
- SQL Server发布订阅功能研究
前提: 发布订阅只能是同一个内网的机器上才能使用,其实这个可以用配置管理器的别名功能设置之后就可以了,外网的也能通过这样的方式来搞. 配置过程参考老D的文章:http://www.cnblogs.co ...
- Bzoj1449 [JSOI2009]球队收益
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 741 Solved: 423 Description Input Output 一个整数表示联盟里所有球 ...