• GCC扩展 __attribute__ ((visibility("hidden")))


      试想这样的情景,程序调用某函数A,A函数存在于两个动态链接库liba.so,libb.so中,并且程序执行需要链接这两个库,此时程序调用的A函数到底来自于a还b呢?

        这取决于链接时的顺序,比如先链接liba.so,这时候通过liba.so的导出符号表就可以找到函数A的定义,并加入到符号表中,链接libb.so的时候,符号表中已经存在函数A,就不会再更新符号表,所以调用的始终liba.so中的A函数

        这里的调用严重的依赖于链接库加载的顺序,可能会导致混乱;gcc的扩展中有如下属性__attribute__ ((visibility("hidden"))),可以用于抑制将一个函数的名称被导出,对连接该库的程序文件来说,该函数不可见的,使用的方法如下:

    -fvisibility=default|internal|hidden|protected
    gcc的visibility说,如果编译的时候用了这个属性,那么动态库的符号都hidden的,除非强制声明。
    1.创建一个c源文件,内容简单

    1. #include<stdio.h>  
    2. #include<stdlib.h>  
    3.  
    4.  
    5. __attribute ((visibility("default"))) void not_hidden ()  
    6. {  
    7. printf("exported symbol ");  
    8. }  
    9.  
    10. void is_hidden ()  
    11. {  
    12. printf("hidden one ");  
    13. }  

    先编译成一个动态库,使用到属性-fvisibility

    1. gcc -shared -o libvis.so -fvisibility=hidden vis.c 

    现在查看

    1. # readelf -s libvis.so |grep hidden  
    2. 7: 0000040c 20 FUNC GLOBAL DEFAULT 11 not_hidden  
    3. 48: 00000420 20 FUNC LOCAL HIDDEN 11 is_hidden  
    4. 51: 0000040c 20 FUNC GLOBAL DEFAULT 11 not_hidden  

    可以看到,属性确实有作用了。

    现在试图link

    1. vi main.c  
    2. int main()  
    3. {  
    4. not_hidden();  
    5. is_hidden();  
    6. return 0;  

    试图编译成一个可执行文件,链接到刚才生成的动态库,

    1. gcc -o exe main.c -L ./ -lvis 

    结果提示:

    1. /tmp/cckYTHcl.o: In function `main':  
    2. main.c:(.text+0x17): undefined reference to `is_hidden'  

    说明了hidden确实起到作用了。

  • 相关阅读:
    Android AsyncTask
    Eclipse 快捷键
    Android JSON数据的读取和创建
    Android 原生listview item伸展收缩效果 (续)
    Android 原生listview item伸展收缩效果
    Android listview 禁止滑动
    Android R.layout. 找不到已存在的布局文件
    Android ScrollView
    Android android:clickable 问题
    Codeforces 388C Fox and Card Game (贪心博弈)
  • 原文地址:https://www.cnblogs.com/lixiaofei1987/p/3198665.html
Copyright © 2020-2023  润新知