Enumeration over structure fields in C

I have several structures in C, and I want to write the following three functions:

get_field_list(...) get_value_by_name(...) set_value_by_name(...) 

The first should return a list of fields defined in the structure. The second and third should receive and set the appropriate field by its name.

I write structures. I wish to use any magic of magic, if necessary. It is good if patients have triplet functions for each structure, but general structures are better. Function icons are also great ...

Basically, I need elementary reflections for structures ....

Relevant: https://natecraun.net/articles/struct-iteration-through-abuse-of-the-c-preprocessor.html

motivation

I am trying to create a DAL (data access level) for my own application written in C. I use SQLite as a database. I need to save various structures and be able to insert \ update \ get (select by key) \ search (select by query), as well as create \ drop the required table.

Basically I want something like Hibernate for C ...

My best idea is to use MACROs or some code generation or script utility to create my structures along with metadata, which I could use to dynamically create all my SQL commands. And also have a small "common" module for implementing all the basic procedures that I need ...

Various or best ideas for solving my current problem will also be appreciated!

+6
source share
2 answers

This can be done using "macromagy," as you suggested:

For each structure, create a header file ( mystruct-fields.h ) as follows:

 FIELD(int, field1) FIELD(int*, field2) FIELD(char*, string1) 

Then in another header ( mystruct.h ) you turn on as many times as you need:

 #define FIELD(T,N) TN; 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 

You can then implement your reflection functions using a table, however you choose.

Perhaps using a different header layer involves reusing the above code for any structure without overwriting it, so your top-level code can only say something like:

 #define STRUCT_NAME mystruct #include "reflectable-struct.h" #undef STRUCT_NAME 

Honestly, it is easier for people who come after you if you just write the structure usually and then write the table out manually; it's much easier to read, your IDE will be able to automatically populate your types, and noticeable warnings in the comments should help prevent people breaking it in the future (and in any case, do you have tests for this right?)

+4
source

The way to do this is to create your structure in a database or XML format or a text file or in any format convenient for you. And use the C program to write the .h file for each structure. An .h file contains a structure, an enumeration of fields, and a char array containing the names of each field. From there, you can build everything you need. It is preferable to use a program generator.

0
source

All Articles