Python解析变长结构体

最近接到一个需求,需要使用 Python 解析 C 来的数据包,而数据包中的格式是通过如下结构体定义的: typedef struct msg_t { int oid; int msg_len; char msg_data[0]; }MSG_T; 其中的 msg_data 字符串的长度是由 msg_len 给出的

最近接到一个需求,需要使用 Python 解析 C 来的数据包,而数据包中的格式是通过如下结构体定义的:

1
2
3
4
5
6
typedef struct msg_t
{
int oid;
int msg_len;
char msg_data[0];
}MSG_T;

其中的 msg_data 字符串的长度是由 msg_len 给出的,因此需要首先解析出 msg_len 的数值,再读取 msg_len 的内容。

在 Python 中可以通过 struct 模块完成这一操作,针对以上数据结构的 python 解析代码如下:

1
2
3
4
5
6
7
8
9
10
OID = 0
msgLen = 0
msgData = ""
sFormat = ""

OID, msgLen = struct.unpack('II', syncMsg[0:8])
sFormat = 'II' + str(msgLen) + 's'
OID, msgLen, msgData = struct.unpack(sFormat, syncMsg)
msgData = msgData.decode()
#print("OID: ", OID, "\nMsgLen: ", msgLen, "\nMsgData: ", msgData.decode())

代码最核心之处在于 unpack 时的单引号部分,其中 I 代表 Int128s 则代表长度为 128 的字符串。在这里首先解析长度,再拼接处数据格式,进而解析。

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 (大写的 i)

unsigned int

integer or long

4

l (小写的 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

4

参考文献


Python解析变长结构体
https://www.frytea.com/post/20200915002100.html
作者
Tianlun Song
发布于
2020年9月15日
更新于
2024年6月10日
许可协议