枚举C中的结构字段
enumerating over a structure fields in C
我在 C 中有几个结构,我想编写以下三个函数:
get_field_list(...)
get_value_by_name(...)
set_value_by_name(...)
第一个应该return 结构中定义的字段列表。第二个和第三个应该按名称获取并设置为适当的字段。
我正在编写结构。如果需要,我愿意使用任何宏魔法。如果每个结构有一个三元组函数也没关系,但是通用结构更好。函数指针也可以...
基本上我想要结构的一些基本反射....
相关事件:
https://natecraun.net/articles/struct-iteration-through-abuse-of-the-c-preprocessor.html
动机
我正在尝试为用 C 编写的本机应用程序构建 DAL(数据访问层)。我正在使用 SQLite 作为数据库。我需要存储各种结构,并且能够插入\更新\获取(select按键)\搜索(select通过查询),还可以创建\删除所需的table.
基本上我想要类似 Hibernate for C 的东西...
到目前为止,我最好的想法是使用 MACRO、某些代码生成实用程序或脚本来创建我的结构以及我可以用来动态构建所有 SQL 命令的元数据。还有一个小的 'generic' 模块来实现我需要的所有基本程序...
解决我的实际问题的不同或更好的想法也将不胜感激!
实现它的方法是让您的结构采用数据库格式或 xml 或文本文件或您喜欢的任何格式。并使用 C 程序为每个结构编写一个 .h 文件。 .h 文件包含 struct 、字段枚举和包含每个字段名称的 char 数组。从那里你可以构建任何你需要的东西。最好使用程序生成器。
可以按照您的建议用 "macro magic" 完成:
为每个结构创建一个 header 文件 (mystruct-fields.h
),如下所示:
FIELD(int, field1)
FIELD(int*, field2)
FIELD(char*, string1)
然后,在另一个 header (mystruct.h
) 中,您可以根据需要多次添加:
#define FIELD(T,N) T N;
struct mystruct {
#include "mystruct-fields.h"
};
#undef FIELD
#define FIELD(T,N) { STRINGIFY(T), STRINGIFY(N), offsetof(mystruct, N) },
#define STRINGIFY1(S) #S
#define STRINGIFY(S) STRINGIFY1(S)
struct mystruct_table {
struct {
const char *type, *name;
size_t offset;
} field[];
} table = {
#include "mystruct-fields.h"
{NULL, NULL, 0}
};
#undef FIELD
然后您可以使用 table 实现您的反射功能,无论您选择什么。
使用另一层 header 文件包含,可以将上述代码重复用于任何结构而不重写它,因此您的 top-level 代码可能只需要这样写:
#define STRUCT_NAME mystruct
#include "reflectable-struct.h"
#undef STRUCT_NAME
老实说,如果您只是正常编写结构,然后手写 table,那么对于追随您的人来说会更容易;它更容易阅读,你的 IDE 将能够 auto-complete 你的类型,评论中的突出警告应该有助于防止人们将来破坏它(无论如何,你确实有这方面的测试吧? )
看看Metaresc library。它在普通 C 中提供反射功能。类型定义的元数据可以从替换标准 C 类型定义语义的自定义宏语言或从编译器调试信息中派生。 README.md
中提供了示例应用程序
我在 C 中有几个结构,我想编写以下三个函数:
get_field_list(...)
get_value_by_name(...)
set_value_by_name(...)
第一个应该return 结构中定义的字段列表。第二个和第三个应该按名称获取并设置为适当的字段。
我正在编写结构。如果需要,我愿意使用任何宏魔法。如果每个结构有一个三元组函数也没关系,但是通用结构更好。函数指针也可以...
基本上我想要结构的一些基本反射....
相关事件: https://natecraun.net/articles/struct-iteration-through-abuse-of-the-c-preprocessor.html
动机
我正在尝试为用 C 编写的本机应用程序构建 DAL(数据访问层)。我正在使用 SQLite 作为数据库。我需要存储各种结构,并且能够插入\更新\获取(select按键)\搜索(select通过查询),还可以创建\删除所需的table.
基本上我想要类似 Hibernate for C 的东西...
到目前为止,我最好的想法是使用 MACRO、某些代码生成实用程序或脚本来创建我的结构以及我可以用来动态构建所有 SQL 命令的元数据。还有一个小的 'generic' 模块来实现我需要的所有基本程序...
解决我的实际问题的不同或更好的想法也将不胜感激!
实现它的方法是让您的结构采用数据库格式或 xml 或文本文件或您喜欢的任何格式。并使用 C 程序为每个结构编写一个 .h 文件。 .h 文件包含 struct 、字段枚举和包含每个字段名称的 char 数组。从那里你可以构建任何你需要的东西。最好使用程序生成器。
可以按照您的建议用 "macro magic" 完成:
为每个结构创建一个 header 文件 (mystruct-fields.h
),如下所示:
FIELD(int, field1)
FIELD(int*, field2)
FIELD(char*, string1)
然后,在另一个 header (mystruct.h
) 中,您可以根据需要多次添加:
#define FIELD(T,N) T N;
struct mystruct {
#include "mystruct-fields.h"
};
#undef FIELD
#define FIELD(T,N) { STRINGIFY(T), STRINGIFY(N), offsetof(mystruct, N) },
#define STRINGIFY1(S) #S
#define STRINGIFY(S) STRINGIFY1(S)
struct mystruct_table {
struct {
const char *type, *name;
size_t offset;
} field[];
} table = {
#include "mystruct-fields.h"
{NULL, NULL, 0}
};
#undef FIELD
然后您可以使用 table 实现您的反射功能,无论您选择什么。
使用另一层 header 文件包含,可以将上述代码重复用于任何结构而不重写它,因此您的 top-level 代码可能只需要这样写:
#define STRUCT_NAME mystruct
#include "reflectable-struct.h"
#undef STRUCT_NAME
老实说,如果您只是正常编写结构,然后手写 table,那么对于追随您的人来说会更容易;它更容易阅读,你的 IDE 将能够 auto-complete 你的类型,评论中的突出警告应该有助于防止人们将来破坏它(无论如何,你确实有这方面的测试吧? )
看看Metaresc library。它在普通 C 中提供反射功能。类型定义的元数据可以从替换标准 C 类型定义语义的自定义宏语言或从编译器调试信息中派生。 README.md
中提供了示例应用程序