c - 在 C 中实现静态函数注册表的可移植方式
问题描述
通过使用节变量属性并依靠 ELF 链接器定义指向自定义节地址的和__start_<section>
符号__stop_<section>
,可以在 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) 交流
#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) 生成文件
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.
解决方案
推荐阅读
- javascript - 根据名称更新状态属性
- java - 谷歌应用引擎中的 Cron 作业与 Spring Boot
- android - 在自定义视图中找不到片段的 id (...) 视图
- scala - 根据 Scala/Apache Spark 中的特定列值更新 grouper 列
- php - 无法在 laravel 5.5 应用程序中正确定义关系
- hql - 如何使用子查询在 hql 中使用内部联接
- javascript - 可以在 Angular 5 中发出 http get 请求之前发生 Google Map API 调用
- r - R:无法从函数内向数据框添加行
- c - 为什么下面的同一个 c prog 有两个输出?
- android - 即使关闭应用程序Android如何保留活动的任务