提取C结构体的字段
我经常需要用其他编程语言写代码,这些代码要和C语言的结构体(struct)进行交互。最常见的情况是用Python编写代码,使用struct或ctypes模块。
通常,我会有一个包含结构体定义的.h文件,我需要手动阅读这些定义,并在我的Python代码中重复这些定义。这非常耗时间,也容易出错,而且当这些定义频繁变化时,保持两者的一致性就变得很困难。
有没有什么工具或库(不一定是C或Python)可以读取.h文件,并生成一个结构化的结构体及其字段的列表?我希望能写一个脚本,自动生成我的Python结构体定义,而不想处理任意的C代码。使用正则表达式大约能解决90%的问题,但剩下的10%就会让我头疼不已。
7 个回答
5
正则表达式在90%的情况下都能很好地工作,但在剩下的10%里却会让人头疼不已。
这些头疼的情况通常发生在你的C代码中出现了一些你在写正则表达式时没想到的语法。这时你会发现,C语言其实并不适合用正则表达式来解析,这样一来,事情就变得不那么有趣了。
不如换个思路:自己定义一个简单的格式,这个格式比C语言的规则要少一些,然后从这个文件生成C语言的头文件和Python接口代码:
define socketopts
int16 port
int32 ipv4address
int32 flags
这样你就可以轻松写一些Python代码,把它转换成:
typedef struct {
short port;
int ipv4address;
int flags;
} socketopts;
同时还可以生成一个Python类,这个类使用struct
来打包和解包三个值(可能其中两个是大端格式,另一个是本地格式,具体由你决定)。
11
如果你在编译C代码的时候加上调试选项(-g
),那么你可以使用
$ pahole /bin/dd … struct option { const char * name; /* 0 8 */ int has_arg; /* 8 4 */ /* XXX 4 bytes hole, try to pack */ int * flag; /* 16 8 */ int val; /* 24 4 */ /* size: 32, cachelines: 1, members: 4 */ /* sum members: 24, holes: 1, sum holes: 4 */ /* padding: 4 */ /* last cacheline: 32 bytes */ }; …
这样获取的信息比直接从C代码中解析要简单很多。