我使用C位字段将数据存储在内存中。为了存档使用,这些数据必须写入一个文件中(以后再与来自另一台机器的数据合并)。直接将位字段保存到文件中似乎是个坏主意,因为数据的排列是特定于实现的。
为此,我编写了一些方法来“序列化”这些位字段,以统一格式保存它们:

/* uint16 is a unsigned int with size 16 */

typedef struct {
    uint16 a : 1;
    /* ... just examples ... */
    uint16 z : 13;
} data;

void save_data(FILE* fp, data d) {
    uint16 tmp;
    tmp = d.a;
    fwrite(&tmp,sizeof(uint16),1,fp);
    /* ... */
    tmp = d.z;
    fwrite(&tmp,sizeof(uint16),1,fp);
}

虽然这是完美的工作,但似乎不太适合扩展,因为在data中添加更多成员还需要将数据添加到保存例程中。
有没有什么技巧可以在更改位字段数据时自动将位字段数据转换为统一格式而无需调整例程/宏?

最佳答案

这里有一个方法。我不能推荐它,但它是在那里,它的工作方式,所以为什么不看看它。这个具体化仍然依赖于平台,但是您可以很容易地切换到独立于平台,可能是人类可读的格式。为了简洁起见,省略了错误处理。

// uglymacro.h
#if defined(DEFINE_STRUCT)

#define BEGINSTRUCT(struct_tag)     typedef struct struct_tag {
#define ENDSTRUCT(struct_typedef)   } struct_typedef;
#define BITFIELD(name,type,bit)     type name : bit;
#define FIELD(name,type)            type name;
#define ARRAYFIELD(name,type,size)  type name[size];

#elif defined(DEFINE_SAVE)

#define BEGINSTRUCT(struct_tag)     void save_##struct_tag(FILE* fp, \
                                                           struct struct_tag* p_a) {
#define ENDSTRUCT(struct_typedef)   }
#define BITFIELD(name,type,bit)     { type tmp; tmp = p_a->name; \
                                      fwrite (&tmp, sizeof(type), 1, fp); }
#define FIELD(name,type)            { fwrite (&p_a->name, sizeof(p_a->name), 1, fp); }
#define ARRAYFIELD(name,type,size)  { fwrite (p_a->name, sizeof(p_a->name[0]), size, fp); }

#elif defined(DEFINE_READ)

#define BEGINSTRUCT(struct_tag)     void read_##struct_tag(FILE* fp, \
                                                           struct struct_tag* p_a) {
#define ENDSTRUCT(struct_typedef)   }
#define BITFIELD(name,type,bit)     { type tmp; fread (&tmp, sizeof(type), 1, fp); \
                                      p_a->name = tmp; }
#define FIELD(name,type)            { fread (&p_a->name, sizeof(p_a->name), 1, fp); }
#define ARRAYFIELD(name,type,size)  { fread (p_a->name, sizeof(p_a->name[0]), size, fp); }

#else
#error "Must define either DEFINE_STRUCT or DEFINE_SAVE or DEFINE_READ"
#endif

#undef DEFINE_STRUCT
#undef DEFINE_READ
#undef DEFINE_WRITE
#undef BEGINSTRUCT
#undef ENDSTRUCT
#undef FIELD
#undef BITFIELD
#undef ARRAYFIELD

结构定义如下:
// mystruct_def.h
BEGINSTRUCT(mystruct)
BITFIELD(a,int,1)
FIELD(b,int)
ARRAYFIELD(c,int,10)
ENDSTRUCT(mystruct)

你这样使用它:
// in mystruct.h file
#define DEFINE_STRUCT
#include "uglymacro.h"
#include "mystruct_def.h"

// in mystruct.c file
#include "mystruct.h"
#define DEFINE_READ
#include "mystruct_def.h"
#define DEFINE_WRITE
#include "mystruct_def.h"

坦率地说,以现代标准来看,这种方法是丑陋的。大约20年前我用过类似的东西,那时候很难看。
另一种选择是使用更人性化的代码生成工具,而不是C预处理器。

关于c - 与平台无关的c位字段存储,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17831578/

10-10 02:19