Python与C++结构体交互

需求:根据接口规范,实现与服务端的数据交互

服务端结构体分包头、包体、包尾

包头C++结构体示例如下

 1 typedef struct head
 2 {
 3     BYTE string1;
 4     BYTE    string2;    //包类型
 5     BYTE    string3;            //版本号,目前为0
 6     char    string4[33];
 7     int        string5;
 8     int        string6;
 9     unsigned int string7;    //包头校验和,以上所有字段的crc32校验和
10     char    string8;
11     char    string9;
12 }protocol_head;

包体C++结构体示例如下

1 typedef struct body
2 {
3     char    sessid[33];
4     int        datalen;
5     BYTE    data[0];
6 };

包尾C++结构体示例如下

1 // 包尾 - 粘包分割
2 typedef struct tag_protocol_tail
3 {
4     BYTE tail[4]
5 }protocol_tail;

根据包头结构体的要求,需要使用CRC32校验

 1 unsigned int GetCRC32(const unsigned char *pbData, int nSize)
 2 {
 3     unsigned long Table[256]={0};
 4     unsigned long  ulPolynomial = 0xEDB88320;
 5
 6     unsigned long  dwCrc;
 7     int i,j;
 8     for(i = 0; i < 256; i++)
 9     {
10         dwCrc = i;
11         for(j = 8; j > 0; j--)
12         {
13             if(dwCrc & 1)
14                 dwCrc = (dwCrc >> 1) ^ ulPolynomial;
15             else
16                 dwCrc >>= 1;
17         }
18         Table[i] = dwCrc;
19     }
20
21     unsigned long dwCrc32 = 0xFFFFFFFF;
22     int idx=0;
23     while(nSize--)
24     {
25         dwCrc32 = ((dwCrc32) >> 8) ^ Table[(pbData[idx]) ^ ((dwCrc32) & 0x000000FF)];
26         idx++;
27     }
28     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校验

 1 def mycrc32(szString):
 2     # 校验码
 3     m_pdwCrc32Table = [0 for x in range(0, 256)]
 4     dwPolynomial = 0xEDB88320
 5     dwCrc = 0
 6     for i in range(0, 255):
 7         dwCrc = i
 8         for j in [8, 7, 6, 5, 4, 3, 2, 1]:
 9             if dwCrc & 1:
10                 dwCrc = (dwCrc >> 1) ^ dwPolynomial
11             else:
12                 dwCrc >>= 1
13         m_pdwCrc32Table[i] = dwCrc
14     dwCrc32 = 0xFFFFFFFFL
15     for i in szString:
16         b = ord(i)
17         dwCrc32 = ((dwCrc32) >> 8) ^ m_pdwCrc32Table[(b) ^ ((dwCrc32) & 0x000000FF)]
18     dwCrc32 = dwCrc32 ^ 0xFFFFFFFFL
19     return dwCrc32

C++和python关于CRC32代码传入参数如何理解?

根据上面C++代码内容,可以看到传入2位参数,它的第一位参数是整个包头+包体+包尾内容,第二位参数是整个包前多少位的长度需要校验

对于python代码,实际上只要传入需要校验的内容。

本文中需要传入的内容实际上是包头的的前6个字段,也就是包头的string1+string2+string3+string4+string5+string6

包头代码

 1 # 包头, data为传入的包体,body_len是包体长度
 2 def qzj_head(data, body_len):
 3     string1 = 100
 4     string2 = 1
 5     string3 = 0
 6     string4 = "6"
 7     string5 = body_len
 8     string6 = body_len
 9
10     string1 = struct.pack(‘B‘, string1 )
11     string2 = struct.pack(‘B‘, string2 )
12     string3 = struct.pack(‘B‘, string3)
13     string4 = struct.pack(‘33s‘, string4 )
14     string5 = struct.pack(‘i‘, string5 )
15     string6 = struct.pack(‘i‘, string6 )
16
17     string7_struct = string1+string2+string3+string4+string5+string6  # 前面的6个字段内容
18     string7_crc32 = des_key.mycrc32(headcrc_str)  # crc32校验
19     string7 = struct.pack(‘I‘, string7_crc32)
20     string8 = 0
21     string9 = 0
22     string8 = struct.pack(‘B‘, string8)
23     string9 = struct.pack(‘B‘, string9)
24
25     request_head = string1+string2+string3+string4+string5+string6+string7+string8+string9+data
26     return request_head

包尾代码

 1 # 包尾,data是传入的包头+包体
 2 def qzj_tail(data):
 3     tail1 = ‘\0‘
 4     tail2 = ‘\0‘
 5     tail3 = ‘\r‘
 6     tail4 = ‘\n‘
 7     tail1 = struct.pack(‘s‘, tail1)
 8     tail2 = struct.pack(‘s‘, tail2)
 9     tail3 = struct.pack(‘s‘, tail3)
10     tail4 = struct.pack(‘s‘, tail4)
11     request_tail = data+tail1+tail2+tail3+tail4
12     return request_tail

包体代码

 1 # 包体, data是要发送的json数据
 2 def body_100(data):
 3     string1 = ‘‘
 4     string2 = len(data)
 5     string3 = data
 6
 7     string1 = struct.pack(‘33s‘, string1)
 8     string2 = struct.pack(‘i‘, string2)
 9     string3 = struct.pack(‘%ds‘ % datalen_num, string3)
10     request_body = string1+string2+string3
11     return request_body, len(request_body)

时间: 2024-08-03 11:30:48

Python与C++结构体交互的相关文章

c++调用python系列(1): 结构体作为入参及返回结构体

最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给游戏服务器,响应消息再交由python进行校验; 开始: 首先是c++调用python这一层需要打通; 幸运的是python自己有一套库提供c/c++进行调用; 下面我贴代码;用的vs2013,python用的2.7 1 // python_c++.cpp : 定义控制台应用程序的入口点. 2 //

python 传递结构体指针到 c++ dll

CMakeLists.txt # project(工程名) project(xxx) # add_library(链接库名称 SHARED 链接库代码) add_library(xxx SHARED xxx.cpp) xxx.cpp #include <iostream> using namespace std; // c++ 结构体定义 struct struck_ { // 股票名,字符串 char * stock_code_; // 开盘价 double stock_open_; };

ctypes 操作 python 与 c++ dll 互传结构体指针

CMakeLists.txt # project(工程名) project(blog-3123958139-1) # add_library(链接库名称 SHARED 链接库代码) add_library(dll_ SHARED dll_.cpp) dll_.cpp #include <iostream> using namespace std; // c++ 结构体定义 struct cpp_struck_ { // 股票代码,字符串 char *stock_name_; // 日期,字符串

Python中对复杂数据结构排序(类似C中结构体数据结构)

Python中排序主要有两个函数:sorted和列表成员函数sort,两者除了调用方式有些区别外,最显著的区别是sorted会新建一个排序好的列表并返回,而sort是修改原列表并排好序.sorted的原型是: sorted(iterable, cmp=None, key=None, reverse=False) sort的原型是: list.sort(cmp=None, key=None, reverse=False) 其中cmp和key都是函数引用,即可以传入函数名.这两个函数都是对list里

结构体和值类型(转)

如果你曾经使用过 Objective-C 或者像 Ruby,Python,JavaScript 这样的语言,可能会觉得 Swift 里的结构体就像外星人一样奇异.类是面向对象编程语言中传统的结构单元.的确,和结构体相比,Swift 的类支持实现继承,(受限的)反射,析构函数和多所有者. 既然类比结构体强大这么多,为什么还要使用结构体?正是因为它的使用范围受限,使得结构体在构建代码块 (blocks) 的时候非常灵活.在本文中,你将会学习到结构体和其他的值类型是如何大幅提高代码的清晰度.灵活性和可

go语言之行--结构体(struct)详解、链表

一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.interface.struct等,所以我们可以理解为go语言中的“类”. 二.struct详解 struct定义 在定义struct成员时候区分大小写,若首字母大写则该成员为公有成员(对外可见),否则是私有成员(对外不可见). type struct_variable_type struct { mem

c语言----结构体--声明及定义

试着写点东西,主要为了巩固学习过的东西. 结构体?C语言中的结构体主要用来表达.定义一些自己想要的类型,例如日期,身份信息等等. 日期:2017-09-10 身份信息:姓名fakke,年龄23,身高180: 可以通过struct来实现.(个人感觉有点像python的字典) 定义的方式: 第一步:声明结构类型: struct   类型名字{ 变量类型1   变量名: 变量类型2  变量名: ... 变量类型3  变量名: }: 第二步:  2定义新的变量 struct date 变量名; 第三步:

转 kobject结构体分析

转载自:http://blog.csdn.net/zhoujiaxq/article/details/7646050 未知作者,以及源地址 ,敬请谅解. kobject是组成设备device.驱动driver.总线bus.class的基本结构. 如果把前者看成基类,则后者均为它的派生产物. device.driver.bus.class构成了设备模型,而kobject内嵌于其中,将这些设备模型的部件组织起来,并形成了sysfs文件系统.kobject就是device.driver.bus.cla

深入了解Windows句柄到底是什么(句柄是逻辑指针,或者是指向结构体的指针,图文并茂,非常清楚)good

总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解.今天比较闲,我上网查了查,光是百度百科词条“句柄”中就有好几种说法,很多叙述还是错误的,天知道这些误人子弟的人是想干什么. 这里我列举词条中的关于句柄的叙述不当之处,至于如何不当先不管,继续往下看就会明白: 1.windows 之所以要设立句柄,根本上源于内存管理机制的问题—虚拟地址,简而言之数据的