• 弱引用和强引用


    如果目标文件对外部目标文件符号进行强引用,但在链接成可执行文件时不能被正确的决议(好奇怪的名称,看看p_51),链接器就会报错,这是对于强引用(Strong Reference)而言的。


    与之相对应还有一种弱引用(Weak Reference),在处理弱引用时,如果该符号有定义,则链接器将对该符号的引用进行决议,如果该符号未被定义,则链接器对于该引用不报错。


    链接器处理强引用和弱引用的过程几乎一样,但是对于未定义的弱引用,链接器不认为它是一个错误;一般,对于未定义的弱引用,链接器默认其值为0,或者是一个特殊值,以便于程序代码能够识别。


    弱引用和弱符号主要用于的链接过程。
    在GCC中,使用__attribute__((weakref))这个扩展关键字来声明对一个外部函数的引用为弱引用,例如下面这段代码:

    __attribute__((weakref)) void foo();

    int main()
    {
        foo();
    }

    我们可以将它编译成一个可执行文件,GCC并不会报链接错误,但是在运行这个可执行文件时,会发生错误。因为当main函数试图调用foo函数时,
    foo函数的地址为0,于是发生了非法地址访问的错误。一个改进的例子是:
    __attritube__((weakref)) void foo();

    int main ()
    {
        if(foo)
            foo();

     return 0;
    }


    弱符号可以被用户定义的强符号所覆盖,从而使得程序可以使用自定义版本的库函数;
    库函数可以对某些扩展功能模块的引用声明为弱引用,当我们将扩展模块与程序链接在一起时,功能模块就可以正常使用;如果我们去掉某些功能模块,
    那么程序也可以正常链接,只是缺少了相应的功能,这使得程序的功能更加容易裁剪和组合。


    附:
    在Linux程序设计中,如果一个程序被设计成可以支持单线程或多线程的模式,就可以通过弱引用的方法来判断当前的程序是链接到了单线程的Glibc库还是
    多线程的Glibc库,从而执行单线程版本的程序或多线程版本的程序。我们可以在程序中定义一个pthread_create函数的弱引用,然后程序在运行时动态
    判断是否链接到pthread库从而决定执行多线程版本还是单线程版本:

          1 #include <stdio.h>                                                                                         
          2 #include <pthread.h>
          3
          4 __attribute__ ((weak)) int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void*), void *);
          5
          6 int main(void)
          7 {
          8     if(pthread_create)
          9     {
         10         printf("This is multi-thread version! \n");
         11         // run the multi-thread version
         12         // main_multi_thread()
         13     }
         14     else
         15     {
         16         printf("This is single-thread version! \n");
         17         // run the single-thread version
         18         // main_single_thread()
         19     }
         20     return 0;
         21 }


    gcc pthread.c -o pt

    gcc pthread.c -lpthread -o pt

  • 相关阅读:
    NSArray的几个方法的简单使用
    内存管理常用知识点总结
    iOS是开发之 对数组中的元素排序后输出
    iOS开发之——单例的几种设计方式
    图论二:图的存储
    图论一:基本概念
    树状数组(hdu-4325,hdu-1166,pat-1057)
    pat1079+1086+1090+1094(树的遍历)感想
    pat 甲级 1086(树的遍历||建树)
    static关键字的功能
  • 原文地址:https://www.cnblogs.com/openix/p/2834872.html
Copyright © 2020-2023  润新知