弱符号、弱引用的扩展机制在库的实现中非常有用。我们在库中可以使用弱符号和弱引用机制,这样对于一个弱符号函数而言,用户可以自定义扩展功能的函数来覆盖这个弱符号函数。
同时我们可以将某些扩展功能函数定义为弱引用,当用户需要使用扩展功能时,就对其进行定义,链接到程序当中,如果用户不进行定义,则链接也不会报错,这使得库的功能可以很方便地进行裁剪和组合。
弱符号示例
// test.h
void test_func(void) { weak_func(); }
// test.c
#include <stdio.h>
void __attribute__((weak)) weak_func(void) {
printf("defualt weak func is running!\n");
}
void test_func(void) { weak_func(); }
使用弱符号
// main.c
#include <stdio.h>
#include "test.h"
int main() {
test_func();
return 0;
}
// ❯ ./test
// defualt weak func is running!
外部强符号,覆盖弱符号
// main.c
#include <stdio.h>
#include "test.h"
void weak_func(void)
{
printf("custom strong func override!\n");
}
int main() {
test_func();
return 0;
}
//❯ ./test
//custom strong func override!
弱引用示例
//test.h
void test_func(void);
//test.c
#include <stdio.h>
// 具体定义: https://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Function-Attributes.html
static __attribute__((weakref("test"))) void weak_ref(void);
void test_func(void) {
if (weak_ref) {
weak_ref();
} else {
printf("weak ref function is null\n");
}
}
//build command => libtest.a
gcc -c test.c; ar -rsc libtest.a test.o
main.c
// 使用默认
#include <stdio.h>
#include <stdarg.h>
#include "test.h"
int main() {
test_func();
return 0;
}
//gcc main.c test.h -L. -ltest -o test
//> weak ref function is null
// 使用外部定义
#include <stdio.h>
#include <stdarg.h>
#include "test.h"
void test(void) { printf("running custom weak ref function!\n"); }
int main() {
test_func();
return 0;
}
//gcc main.c test.h -L. -ltest -o test
//> running custom weak ref function!