перечисление полей структуры в C

У меня есть несколько структур в C и я хочу написать следующие три функции:

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

первый должен возвращать список полей, определенных в struct. Второй и третий должны получить и установить соответствующее поле по его имени.

Я пишу структур. Я готов использовать любой макрос магия, если требуется. Это нормально, если у меня есть триплет функций для каждой структуры, но общие структуры лучше. Указатели функций также штраф...

в основном я хочу некоторые элементарные отражения для структур....

уместное: https://natecraun.net/articles/struct-iteration-through-abuse-of-the-c-preprocessor.html

мотивация

Я пытаюсь создать DAL (уровень доступа к данным) для собственного приложения, написанного на C. я использую SQLite в качестве БД. Мне нужно хранить различные структуры и иметь возможность вставлять update get (select by key) search (select by query), а также создать удалить требуемую таблицу.

в основном я хочу что-то вроде Hibernate для C ...

моя лучшая идея до сих пор-использовать макросы, или некоторую утилиту генерации кода, или скрипт, чтобы создать мои структуры вместе с метаданными, которые я мог бы использовать для динамического построения всех моих команд SQL. А также иметь небольшой общий-модуль для выполнения всех основных процедур, которые мне нужны...

различные или лучшие идеи для решения моей реальной проблемы также будут ценю!

2 ответов


Это можно сделать с помощью "макро-магии", как вы предложили:

для каждой структуры создайте файл заголовка (mystruct-fields.h) такой:

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

затем в другом заголовке (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

затем вы можете реализовать свои функции отражения, используя таблицу, однако вы выбрать.

возможно, используя другой слой заголовочного файла, можно повторно использовать приведенный выше код для любой структуры без переписывая его, ваш код верхнего уровня может только сказать что-то вроде:

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

честно говоря, это легче для людей, которые приходят после вас, если вы просто пишете структуру нормально, а затем выписываете таблицу вручную; это намного проще читать, Ваша IDE сможет автоматически заполнять ваши типы, и видные предупреждения в комментариях должны помочь предотвратить людей, нарушающих его в будущем (и в любом случае, у вас есть тесты для этого права?)


способ сделать это-иметь свою структуру в формате базы данных или xml или текстовом файле или любом удобном формате. И используйте программу C, чтобы написать a .файл H для каждой структуры. Этот.H файл содержит структуру, перечисление полей и массив символов, содержащий имена каждого поля. Оттуда вы можете построить все, что вам нужно. Предпочтительно использовать программный генератор.