利用 constructor 属性完成 module_init() 设计模式
一、简介
1. __attribute__语法格式为:__attribute__ (( attribute-list ))
若函数被设定为 constructor 属性,则该函数会在 main() 函数执行之前被自动的执行。类似的,若函数被设定为 destructor 属性,则该函数会在 main() 函数执行之后或者 exit() 被调用后被自动的执行。
2. 当存在多个 __attribute__((constructor)) 修饰的函数时,也不用持锁,因为是单线程执行的。
3. 还可以使用 __attribute__((constructor(prio))) 指定优先级,从而决定调用次序,优先级prio取值范围是 0--65535,其中 0--100 是预留的,不能使用,优先级数值越小优先级越高,越优先被执行调用。只要指定了优先级,就算是指定的优先级是65535也还是会比没有指定优先级的先调用。
二、 测试例子
1. C程序
#include__attribute__((constructor)) void before_main() { printf("before main.\n"); } __attribute__((destructor)) void after_main() { printf("after main.\n"); } int main() { printf("in main.\n"); return 0; } /* //执行结果: $ ./pp before main. in main. after main. */
2. C++程序
#includeusing namespace std; __attribute__((constructor)) void before_main() // void 在前后都行 { //cout<<"Before Main"< //注释掉就不 Segmentation fault 了。 int i; i++; } __attribute__((destructor)) void after_main() { cout<<"After Main"<<endl; } class AAA{ public: AAA(){ cout<<"AAA construct"<<endl; } ~AAA(){ cout<<"AAA destructor" <<endl; } }; AAA A; //全局类对象 int main() { cout<<"in main"<<endl; return 0; } /* 执行结果: $ ./pp AAA construct in main AAA destructor After Main */
注:测试发现,C++中 __attribute__((constructor)) 修饰的函数中不能执行 cout<<"..."< 1. 实现 Linux内核中 module_init() 是通过链接器脚本实现的,用户空间程序可以使用 constructor 属性实现。 (1) core.c (2) core.h (3) camera.c (4) led.c 2. 测试 3. 若需要再添加其它命令,值需要添加一个文件并注册即可,不用改原有文件。
三、实现类似Linux内核中 module_init() 的设计模式#include
#define FUNC_NUM 16
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
struct function {
int id;
int (*init)(void);
int (*execute)(int code);
void (*release)(void);
};
extern struct function *g_functions[FUNC_NUM];
#define function_register(name) \
void __attribute__((constructor)) function_##name##_register(void) \
{ \
int i; \
for (i = 0; i < ARRAY_SIZE(g_functions); i++) { \
if (!g_functions[i]) { \
g_functions[i] = &func_##name; \
break; \
} \
} \
printf("%s, id=%d.\n", __func__, func_##name.id); \
}
#include
#include
$ gcc *.c -o pp
$ ./pp
function_camera_register, id=1.
function_led_register, id=2.
camera_init called.
led_init called.
camera_release called.
led_release called.
$ ./pp 1
function_camera_register, id=1.
function_led_register, id=2.
camera_init called.
led_init called.
camera_execute called.
camera_release called.
led_release called.