我有一个 C 库,用于存储包含多个字段的记录。Schema 是从文本文件中读入的,包括记录中每个字段的类型。
为了简化问题,假设我有
typedef enum my_type_enum
{
INT32, //32-bit integer
MYSTRUCT, //some struct I have, details irrelevant
...
} my_type_enum;
typedef struct my_var
{
my_type_enum typetag;
unsigned char* data;
} my_var;
my_var myrecord[numfields];
模式文件说明 myrecord 的每个字段是否应包含 int32_t 或 mystruct。我的库读取模式文件,并为 myrecord 中的每个 my_var 设置标签并为数据分配适量的空间。
my_var 是不透明的,客户端程序基本上使用,用于简单数据
void set(my_var* record, size_t field, void * src)
{
memcpy(record[field].data, src, datatypes[record[field].typetag].size);
}
int32_t x = 5;
set(myrecord, 0, &x);
将值存储在记录中,并使用类似的 get() 将内容取出。
一旦数据在 my_var 中,标记的 my_var 类型就允许进行类型检查,但是如果架构说记录包含三个 INT32,那么当您尝试 set() 数据时,当然没有什么可以检查 src 指向 int32_t 而不是 mystruct进入 my_var。
显然,在将 int32_t* 或 mystruct* 转换为 void* 之前,需要在包装 set() 的东西中进行检查。我见过使用 typeof() 诡计进行编译时检查。我觉得我想要的可能是不可能的,但你永远不会知道所有的技巧......
有什么比提供在客户端程序编译时读取模式并生成 set_CHECKED() 包装宏的工具更好的方法,如果有人试图将 int32_t 复制到标记为保存 mystruct 的 my_var 中,则会出现编译器错误?GCC 扩展很好。