gpt4 book ai didi

c - c 位域的平台独立存储

转载 作者:太空宇宙 更新时间:2023-11-04 03:54:28 25 4
gpt4 key购买 nike

我使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com