Я пытаюсь найти способ использовать вложенные глобальные структуры в качестве своего рода пространства имен API для моей библиотеки C.
В частности, я хочу показать одну Primary
‘структуру пространства имен’, которая содержит другие такие структуры (например, Primary.Secondary
), которые сами содержат указатели на функции (Primary.Secondary.a_function()
).
Я абстрагировал следующий (относительно) простой пример того, что я хочу сделать:
main.c
:
#include "Primary.h"
int main () {
Primary.Secondary.a_function();
return 0;
}
Primary.h
:
#if !defined(SECONDARY_H)
# include "Secondary.h"
#endif
struct Primary_struct {
struct Primary__Secondary_struct Secondary;
} extern Primary;
Primary.c
#include "Primary.h"
struct Primary_struct Primary = {
.Secondary = Primary__Secondary
};
Secondary.h
:
struct Primary__Secondary_struct {
void (*a_function) (void);
void (*another_function) (void);
} extern Primary__Secondary;
Secondary.c
#include "Secondary.h"
#include <stdio.h>
void Primary__Secondary__a_function (void);
void Primary__Secondary__another_function (void);
struct Primary__Secondary_struct {
.a_function = Primary__Secondary__a_function,
.another_function = Primary__Secondary__another_function
} extern Primary__Secondary;
void Primary__Secondary__a_function(void) {
Primary.Secondary.another_function();
}
void Primary__Secondary__another_function(void) {
printf("run!\n");
}
Когда я пытаюсь скомпилировать это, я сталкиваюсь со следующей ошибкой компилятора:
> C -O0 Primary.c Secondary.c main.c
Primary.c:3:33: error: initializer element is not a compile-time constant
struct Primary_struct Primary = {
^
1 diagnostic generated.
Следует отметить, что в идеале переменные Primary
и Primary__Secondary
должны быть const
. Я волновался, что дополнительная сложность усугубит проблему ... так что пока я оставил этот аспект вне себя.
Проблема, по-видимому, заключается в том, что по какой-то причине, даже если она установлена как const
и содержит только элементы, присутствующие во время компиляции, структура Primary__Secondary
не является константой времени компиляции и, следовательно, не может быть сохранена другая структура во время компиляции. Вероятно, я могу обойти это, настроив все интерфейсы во время выполнения, но ... это выглядит по-настоящему хакерским решением. Я ищу какие-то альтернативные решения этой проблемы, чтобы вы могли придумать больше, чем я могу.
( Примечание : Это относится к этому вопросу , но существенно отличается и немного более конкретен.)