zoukankan      html  css  js  c++  java
  • 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确实起到作用了。

  • 相关阅读:
    InfoQ访谈BPEL4People代表
    传 IBM 拟 4 月 6 日宣布收购 Sun
    NetBeans 6.7 Milestone 3 Now Available for Download!
    Intel比AMD高明在哪里?
    InfoQ访谈BPEL4People代表
    Linux 3.8.1 电源管理之OMAP Voltage Domain分析
    Readline简介 Linux技术问答 Linux中国 | Linux.cn 我们的Linux中文社区
    更改日期
    JAVA研发工程师(YF)
    一键解决Ubuntu下安装Eclipse Android/C/C++ 开发环境
  • 原文地址:https://www.cnblogs.com/lixiaofei1987/p/3198665.html
Copyright © 2011-2022 走看看