GCC扩展 __attribute__

转自:http://www.th7.cn/Program/cp/2012/03/24/66030.shtml


试想这样的情景,程序调用某函数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/n");  
  8. }  
  9.  
  10. void is_hidden ()  
  11. {  
  12. printf("hidden one/n");  
  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确实起到作用了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值