Perl处理c的结构体

最近需要观察一下系统的通信情况, 想用perl写个简单的模拟程序. 然后又碰到了了一个老问题: 如何使用perl来解析二进制数据. 以前针对这种情况基本可以使用pack/unpack来解决. 但是最近的数据着实让感到有点棘手, 使用pack/unpack进行操作会很不方便:

  1. 结构体成员数目多
  2. 成员同样是结构体
  3. 对齐问题

当结构体比较简单时, 上面几点都不是问题, 但是如果想要解析的结构体struct fun像这样子:

strucure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
enum xtype {
    T1,
    T2,
    T3,
    T4,
    TMAX,
};

struct foo {
    int            cnt;
    time_t         time;
    unsigned long  tt;
};

struct bar {
    int            cnt;
    time_t         time;
    unsigned long  tt;
};

struct baz {
    int            cnt;
    time_t         time;
    unsigned long  tt;
};

struct fun {
    struct foo sfoo;
    struct bar sbar;
    strict baz sbaz;
    int kinds[TMAX];
};

如果像这样子, 写对应的pack函数的format就蛋疼了. 有没有什么简单的办法呢? 答案是肯定的.

Convert::Binary::C模块

perlmonks上有人提到了Convert::Binary::C模块. 对于这个模块, 我只想说两个字: 好用~ 该模块的文档非常详细, 我尤其喜欢作者前面介绍开发这个模块的过程, 给我蛮多启发的.

因为文档写的很棒, 这里就不介绍具体的使用了, 但有两个注意点:

  1. 模块自带了一个程序: ccconfig. 它用于自动生成对应的config. 这里推荐仅仅使用里面的Include和部分的Define定义.
  2. 该模块可以直接读取对应的结构体对应文件, 但还是推荐用手动parse的方式(只parse所需的内容+对应的头文件). 原因是很多时候头文件定义容易引入外部的文件或者包含一些函数, 造成混乱.

有相关需求的同学可以尝试一下这个模块, 真的非常好用~

Comments