我写了一个支持c语言结构体遍历的小工具

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
回复
weiweishuo
帖子: 53
注册时间: 2012-06-29 13:05

我写了一个支持c语言结构体遍历的小工具

#1

帖子 weiweishuo » 2013-06-05 21:58

我这个小工具的名字叫mw(取make width意)。
一般遍历结构体是为了读它的member,逐一做某种种操作。看下面一个结构体:
file:t.h

代码: 全选

typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned char __u8;
typedef unsigned __u32;
typedef unsigned short __le16;
 
typedef struct{
    int is_boy_girl;
    __u32 how_old;
    u8 hand_num;
    u8 feet_num;
    __u8 eyes_num;
    __u8 head_num;
    __u8 finger_count[12];
    u16 heigh_cm;
    __u16 weight_kg;
}BABY;
让你打印它所有的mmeber的信息,你会怎么办?用一个长长的printf,还是用9个稍短的printf?如果有30个成员呢?
我在t.h里再加上几句代码:

代码: 全选

static int memberwidth_BABY[]={4,4,1,1,1,1,1,2,2};//记录每个成员的变量长度
static char* membername_BABY[]={"is_boy_girl","how_old","hand_num","feet_num","eyes_num","head_num","finger_count[12]","heigh_cm","weight_kg"};//记录每个成员的描述信息
static int memberlen_BABY[]={1,1,1,1,1,1,12,1,1};//记录每个成员数组长度(如果它不是数组,就=1)
是不是有了曙光,有了这几句,就可以遍历了。
但是,手工添加这三行代码的工作量很大...
这就是mw的基本功能,自动在源代码里添加这几行代码。

先看看mw实现的效果,打印一个结构体只要两句代码:

代码: 全选

#include<stdio.h>
#include"t.h"
#include"struinfo.h"
void main(void){
    BABY baby={1,10,2,2,2,1,{0,1,2,3,4,5,6,7,8,9,10,11},100,30};
 
    //printf member-infomation of baby
    workon((char*)&baby,membername_BABY,memberwidth_BABY,memberlen_BABY,sizeof(memberwidth_BABY)/4);   
    struinfo();
}
编译链接,运行输出:

代码: 全选

@struinfo:
is_boy_girl: 1 
how_old: 10 
hand_num: 2 
feet_num: 2 
eyes_num: 2 
head_num: 1 
finger_count[12]: 0  1  2  3  4  5  6  7  8  9  10  11 
heigh_cm: 100 
weight_kg: 30 
很方便吧。调用的workon函数和struinfo()函数是我自己写的,它放在struinfo.c模块里,是mw工具的一个附加功能,需要编译链接到你的源文件里。mw在源代码里插入那几行关键代码,struinfo.c就是根据那几行代码,封装遍历结构体并打印出来的操作(我只封装了这个功能,因为我遍历结构体的目的几乎就是打印)。
再说一说mw工具怎么用,分三步走:
1,在.h文件里,用typedef wstruct{...声明你想要遍历的结构体,例如上面的t.h要写成这样:

代码: 全选

//取这么多别名,是为了试验mw对结构体成员类型的识别
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned char __u8;
typedef unsigned __u32;
typedef unsigned short __le16;
 
typedef wstruct{//你没看错,这儿就是wstruct,是为了给mw识别
    int is_boy_girl;
    __u32 how_old;
    u8 hand_num;
    u8 feet_num;
    __u8 eyes_num;
    __u8 head_num;
    __u8 finger_count[12];//多了两根
    u16 heigh_cm;
    __le16 weight_kg;
}BABY;
2,mw必须和.h文件放在同意文件夹,在gcc编译之前,运行命令 ./mw xx.h(你声明的结构体放在哪个.h文件里)。再打开xx.h,你会发现它变成这样子了:

代码: 全选

//取这么多别名,是为了试验mw对结构体成员类型的识别
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned char __u8;
typedef unsigned __u32;
typedef unsigned short __le16;
 
typedef struct{//“w"标记已经被自动去掉
    int is_boy_girl;
    __u32 how_old;
    u8 hand_num;
    u8 feet_num;
    __u8 eyes_num;
    __u8 head_num;
    __u8 finger_count[12];//多了两根
    u16 heigh_cm;
    __le16 weight_kg;
}BABY;//下面多出来几行代码
static int memberwidth_BABY[]={4,4,1,1,1,1,1,2,2};
static char* membername_BABY[]={"is_boy_girl","how_old","hand_num","feet_num","eyes_num","head_num","finger_count[12]","heigh_cm","weight_kg"};
static int memberlen_BABY[]={1,1,1,1,1,1,12,1,1};
3,其实前两步已经完成了mw的使命,你可以根据mw生成的3个数组,做灵活操作。struinfo.c里只封装了遍历机构体并打印的操作,你想用的话,要包含struinfo.h头文件,并跟struinfo.c一起编译链接。
------------------------------------------------------------------------------

ps:
1,如果有哪位高手知道更好的方法,尽管骂来,洗耳恭听。
2,本贴不欢迎讨论【结构体是否需要遍历,值得遍历】等问题。
3,源代码我都上传到这儿,写得很丑,轻易不要看,看不懂也别生气。http://download.csdn.net/detail/weiweishuo/5496587(收了1分,我下次再不收了...)
4,目前的mw功能很弱,只支持基元数据成员和数组成员,其它的结构体成员,union,指针成员还不被支持。(但可以被支持)
小工具的自动化程度还不高,需要手动输入头文件,而且一次只能处理一个wstruct标签,而且你声明wstruct类型的数据结构时,代码一定要特别规矩:例如wstruct和{之间不能有空格,两句代码不能同行....确切说,它现在还不实用。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 我写了一个支持c语言结构体遍历的小工具

#2

帖子 eexpress » 2013-06-06 8:52

你给出命令和输出的例子,更容易看明白是做啥的。
说不定有现成的,或者类似的软件。
● 鸣学
infidel
帖子: 136
注册时间: 2012-03-28 10:16

Re: 我写了一个支持c语言结构体遍历的小工具

#3

帖子 infidel » 2013-06-06 14:33

你是想玩反射吧~
如果不是下面的东西就可以不用看了。
---
如果想玩反射,可以看看《深入浅出MFC》的第三章里面讲的一些东西,好像有个RunClass的东西,可以帮你完成功能比较强大的反射。
还有个东西叫做VCF(visual component frame work)一个GUI框架,里面的反射也是极好的。
回复