弱符号_弱引用

弱符号、弱引用的扩展机制在库的实现中非常有用。我们在库中可以使用弱符号和弱引用机制,这样对于一个弱符号函数而言,用户可以自定义扩展功能的函数来覆盖这个弱符号函数。
同时我们可以将某些扩展功能函数定义为弱引用,当用户需要使用扩展功能时,就对其进行定义,链接到程序当中,如果用户不进行定义,则链接也不会报错,这使得库的功能可以很方便地进行裁剪和组合。

弱符号示例

// 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!