Портативный способ реализации статической функции реестра в C
Реализовать статический реестр функций в C для gcc/clang можно, используя атрибут переменной section и полагаясь на компоновщик ELF для определения __start_<section>
а также __stop_<section>
символы, указывающие на адрес пользовательского раздела.
(См. Ниже пример использования этого подхода, который должен проиллюстрировать это.)
Этот подход, однако, очень специфичен для GCC, ELF и Unix/Linux.
Есть ли альтернативный подход для решения этой же проблемы статического реестра функций, только более переносимым способом?
В частности, я хотел бы иметь возможность использовать компилятор MSVC для Windows.
В качестве примера рассмотрим эту программу, используя этот набор исходных файлов:
1) registry.h
struct reg_func {
const char *name;
int (*func)(void);
};
#define REGISTER_FUNC(name) \
static int func_ ## name(void); \
static struct reg_func descr_ ## name \
__attribute__((section("registry"))) \
= { # name, func_ ## name }; \
static int func_ ## name(void)
extern struct reg_func __start_registry;
extern struct reg_func __stop_registry;
2) переменный ток
#include "registry.h"
REGISTER_FUNC(a) {
return 1;
}
3) до н.э.
#include "registry.h"
REGISTER_FUNC(b) {
return 4;
}
4) куб.
#include "registry.h"
REGISTER_FUNC(cde) {
return 999;
}
5) main.c
#include <stdio.h>
#include "registry.h"
int main(int argc, char *argv[]) {
struct reg_func *p;
for (p = &__start_registry; p < &__stop_registry; p++) {
printf("Function %s returned %d.\n", p->name, p->func());
}
return 0;
}
6) Makefile
registry: main.o a.o b.o c.o
$(CC) -o $@ $^
Сборка с:
$ make
cc -c -o main.o main.c
cc -c -o a.o a.c
cc -c -o b.o b.c
cc -c -o c.o c.c
cc -o registry main.o a.o b.o c.o
Выполнить с:
$ ./registry
Function a returned 1.
Function b returned 4.
Function cde returned 999.