我struct
在现有程序中有一个非常大的。该结构包含大量位域。
我希望保存其中的一部分(例如,150 个字段中的 10 个)。
我用来保存子类的示例代码是:
typedef struct {int a;int b;char c} bigstruct;
typedef struct {int a;char c;} smallstruct;
void substruct(smallstruct *s,bigstruct *b) {
s->a = b->a;
s->c = b->c;
}
int save_struct(bigstruct *bs) {
smallstruct s;
substruct(&s,bs);
save_struct(s);
}
我也希望选择它的哪一部分不会太麻烦,因为我希望时不时地改变它。我之前提出的幼稚方法非常脆弱且无法维护。当扩展到 20 个不同的字段时,您必须同时更改smallstruct
和substruct
函数中的字段。
我想到了两种更好的方法。不幸的是,两者都需要我使用一些外部CIL 之类的工具来解析我的结构。
第一种方法是自动生成substruct
函数。我将只设置 的结构smallstruct
,并有一个程序来解析它并substruct
根据 中的字段生成函数smallstruct
。
第二种方法是构建(使用 C 解析器)关于 的元信息bigstruct
,然后编写一个库,允许我访问结构中的特定字段。这就像 Java 类反射的临时实现。
例如,假设没有结构对齐,对于 struct
struct st {
int a;
char c1:5;
char c2:3;
long d;
}
我将生成以下元信息:
int field2distance[] = {0,sizeof(int),sizeof(int),sizeof(int)+sizeof(char)}
int field2size[] = {sizeof(int),1,1,sizeof(long)}
int field2bitmask[] = {0,0x1F,0xE0,0};
char *fieldNames[] = {"a","c1","c2","d"};
我将使用此函数获取第i
th字段:
long getFieldData(void *strct,int i) {
int distance = field2distance[i];
int size = field2size[i];
int bitmask = field2bitmask[i];
void *ptr = ((char *)strct + distance);
long result;
switch (size) {
case 1: //char
result = *(char*)ptr;
break;
case 2: //short
result = *(short*)ptr;
...
}
if (bitmask == 0) return result;
return (result & bitmask) >> num_of_trailing_zeros(bitmask);
}
这两种方法都需要额外的工作,但是一旦解析器在您的 makefile 中 - 更改子结构是轻而易举的事。
但是,我宁愿在没有任何外部依赖的情况下这样做。
有没有人有更好的主意?在我的想法有什么好处的地方,我的想法在互联网上是否有一些可用的实施方式?