通过使用section variable attribute并依靠ELF链接器定义指向自定义节地址的the __start_<section>
and __stop_<section>
symbols,可以在C中为gcc / clang实现静态功能注册表。
(有关使用此方法的示例,请参见下文,其中应说明这一点。)
但是,这种方法非常特定于GCC,ELF和Unix / Linux。
是否有其他方法只能以更便携的方式解决静态函数注册表的同一问题?
特别是,我希望能够将Windows的MSVC编译器作为目标。
作为示例,请考虑使用以下源文件集的程序:
1)注册表。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)a.c
#include "registry.h"
REGISTER_FUNC(a) {
return 1;
}
3)b.c
#include "registry.h"
REGISTER_FUNC(b) {
return 4;
}
4)c.c
#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.