试想这样的情景,程序调用某函数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. __attribute ((visibility("default"))) void not_hidden ()
  4. {
  5. printf("exported symbol\n");
  6. }
  7. void is_hidden ()
  8. {
  9. printf("hidden one\n");
  10. }

先编译成一个动态库,使用到属性-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;
  7. }

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

  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确实起到作用了。

GCC扩展 __attribute__ ((visibility("hidden")))的更多相关文章

  1. [转]GCC系列: __attribute__((visibility("")))

    在 objc-api.h 里面有很多关于__attribute__ 的定义. 例如 #if !defined(OBJC_VISIBLE) # if TARGET_OS_WIN32 # if defin ...

  2. GCC扩展(转--对看kernel代码有帮助

    http://my.oschina.net/senmole/blog?catalog=153878 Linux Kernel的代码,上次就发现一个结构体的定义形式看不懂,后来才知道它用的不是标准的AN ...

  3. IOS UIKIT_EXTERN, __attribute__((visibility ("default"))) 是啥玩意?

    问题提出 在学习IOS时候,碰到一个函数NSStringFromCGPoint (UIGeometry.h) 其原型是 UIKIT_EXTERN NSString *NSStringFromCGPoi ...

  4. JQuery可见性过滤选择器:hidden无法获取通过visibility:hidden样式隐藏的元素-遁地龙卷风

    1.版本问题 如果你可以获取下列元素 <input type="hidden"/> <div style="display:none"> ...

  5. style="visibility: hidden" 和 style=“display:none”区别

    大多数人很容易将CSS属性display和visibility混淆,它们看似没有什么不同,其实它们的差别却是很大的. visibility属性用来确定元素是显示还是隐藏的,这用visibility=& ...

  6. CSS样式“display:none”与“visibility:hidden”区别

    CSS样式“display:none”和“visibility:hidden”都可以实现将页面元素隐藏,但是具体的效果是有差别的!下面通过两个小实验来说明这种差异. 实验代码: <!DOCTYP ...

  7. display:none与visibility: hidden的区别

    display:none和visibility: hidden都能把网页上某个元素隐藏起来,但两者有区别: display:none ---不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失. ...

  8. 再谈visibility:hidden和display:none

    之前写过一篇有关visibility:hidden和display:none的文章:为什么要用用visibility:hidden;代替display:none;?主要是从浏览器性能方面入手,却没写两 ...

  9. 为什么要用visibility:hidden;代替display:none;?

    为什么要用用visibility:hidden;代替display:none;?因为后者更加消耗浏览器: css绘制画面有两种形式:repaint 和reflow,当我们更改css属相如backgro ...

随机推荐

  1. Amazon Alexa 语音识别2 : 设置

    开发者建立的Skill的主要设置项目都在Skill的console内.需要填写的东西大致有以下几个: 1.Skill 名字.这个名字是用户用来唤醒你这个Skill的. 2.Intent Schema: ...

  2. js pix

    window.onload = function () { var img = new Image(); img.src = '1.gif'; var ctx = document.querySele ...

  3. Java注释模板

    /**   *    * 项目名称:${project_name}   * 类名称:${type_name}   * 类描述:   * 创建人:${user}   * 创建时间:${date} ${t ...

  4. 图文详解如何搭建Windows的Android C++开发环境

    原地址:http://www.apkbus.com/android-18595-1-1.html //================================================= ...

  5. PHP dirname() 函数

    定义和用法 dirname() 函数返回路径中的目录部分. 语法 dirname(path) 参数 描述 path 必需.规定要检查的路径. 说明 path 参数是一个包含有指向一个文件的全路径的字符 ...

  6. asp.net 简单实现禁用或启用页面中的某一类型的控件

    我们在提交一个表单的时候,可能由于网络或服务器的原因,处理很慢,而用户在处理结果出来之前反复点击按钮提交.这样很容易造成不必要的麻烦甚至是错误.说了这么多,其实就是要实现一个禁用某些控件的一种功能.好 ...

  7. asp.net 框架初接触

    1. 在web层的Default.aspx里只有最基本的UI代码 2. 在web层的Default.aspx.cs里第一行创建一个用户业务对象UserBO (注意添加引用,下同) protected ...

  8. python属性查找

    python中执行obj.attr时,将调用特殊方法obj.__getattribute__('attr'),该方法执行搜索来查找该属性,通常涉及检查特性.查找实例字典.查找类字典以及搜索基类.如果搜 ...

  9. 2、RenderScript的计算(2013.05.07)

    一.官方文档翻译: Android Renderscript计算 参考网址: http://blog.csdn.net/fireofstar/article/details/7748143 http: ...

  10. linux编译安装git

    我的博客:www.while0.com 用的centos6.4中自带的git,版本为1.7.1,配置好github的sshkey后,clone下来的项目无法提交,提示: fatal: Unable t ...