根据说明文档“How To Write Shared Libraries"介绍,

有四种方法:

1. 在方法声明定义时,加修饰:__attribute__((visibility("hidden")))

就是说将不公开的函数都加上这个属性,没加的就是可见的

2. gcc 在链接时设置 -fvisibility=hidden,则不加 visibility声明的都默认为hidden; gcc默认设置 -fvisibility=default,即全部可见;

在gcc中加了这个设置之后表示所有的函数都是对外不可见了,然后在代码里面对于想公开的函数加上 __attribute__((visibility("default")))

3. 使用export map,gcc -Wl,--version-script=export.map, 在export.map中指定

{

global:export_func;

local:*;

};

则除了export_func外,全部为内部可见;

4. 使用libtool的export-symbols选项,没试过,略;

以上方法,对于gcc的visibility功能需要 gcc 4以上版本,

常见的宏,用于等同于 windows下的 __declspec(dllexport)(摘自:http://gcc.gnu.org/wiki/Visibility):

#if defined _WIN32 || defined __CYGWIN__

  #ifdef BUILDING_DLL

    #ifdef __GNUC__

      #define DLL_PUBLIC __attribute__((dllexport))

    #else

      #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.

    #endif

  #else

    #ifdef __GNUC__

      #define DLL_PUBLIC __attribute__((dllimport))

    #else

      #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.

  #endif

  #define DLL_LOCAL

#else

  #if __GNUC__ >= 4

    #define DLL_PUBLIC __attribute__ ((visibility("default")))

    #define DLL_LOCAL  __attribute__ ((visibility("hidden")))

  #else

    #define DLL_PUBLIC

    #define DLL_LOCAL

  #endif

#endif

实践中发现几个有意思的东西[实验环境为ubuntu 9.10, gcc 4.4.1]:

1. gcc -fvisibility=hidden 只在链接时传入的.c文件起作用,对.o文件不其作用;

比如test.c test1.c, 使用以下命令:

gcc -shared -fvisibility=hidden -o test.so test.c test1.c

和命令

gcc -c test.c test1.c

gcc -shared -fvisibility=hidden -o test.so test.o test1.o

生成的test.so中的对应可见性是不一样的, 使用“readelf -s test.so”查看发现:

第一个达到预期目的,即将两个.c文件中的functions设为HIDDEN,

而第2个则不行,-fvisibility=hidden不起作用;

再用gcc -shared -fvisibility=hidden -o test.so test.o test1.c

生成的so,则可发现test1.c中的函数为HIDDEN,但test.o中的函数仍为DEFAULT;

2. 实验通过export map的方法,通过readelf总是发现函数仍然可见,后来搜索发现:

需同时使用ld --retain-symbols-file --version-script 两个选项方能达到 使得elf文件中的.dynsym和.symtab

中的符号表都得到控制;其中--retain-symbols-file控制静态符号表,--version-script则对应dynamic符号表;
另外可以参考 http://blog.csdn.net/shuiyingzi5/article/details/8108190


转自 http://blog.csdn.net/zdragon2002/article/details/6061962

Linux下gcc编译控制动态库导出函数小结的更多相关文章

  1. linux下 GCC编译链接静态库&动态库

    静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 ...

  2. Linux 下 GCC 编译共享库控制导出函数的方法

    通过一些实际项目的开发,发现这样一个现象,在 Windows 下可以通过指定 __declspec(dllexport) 定义来控制 DLL(动态链接库)中哪些函数可以导出,暴露给其他程序链接使用,哪 ...

  3. C++ 动态库导出函数名“乱码”及解决

    C++ 动态库导出函数名“乱码”及解决 刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都“乱码”了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // ...

  4. 【图文】[新手]C++ 动态库导出函数名“乱码”及解决

    刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...

  5. linux下gcc编译的参数详细说明

    参考网址:1 http://hi.baidu.com/zengzhaonong/item/f1f9383565fa5c302e0f8125 gcc使用方法 汇总 2 http://s99f.blog. ...

  6. Linux环境g++编译GDAL动态库

    一.编译步骤 解压下载的GDAL源程序,并在命令行中切换到解压目录. tar -xzvf gdal-2.1.3.tar.gz cd gdal-2.1.3 GDAL可通过configure来实现一些自定 ...

  7. linux下gcc编译多个源文件、gdb的使用方法

    一. gcc常用编译命令选项 假设源程序文件名为test.c. 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理.汇编.编译并链接形成可执行文件.这里未指定输出文件,默认 ...

  8. Linux环境g++编译TinyXML动态库

    除了CMarkup,tinyxml也是C/C++下解析XML很好的工具.在linux下用g++编译tinyxml的步骤如下(tinyxml版本2.6.2): 进入tinyxml解压目录,用文本编辑器打 ...

  9. linux下,一些关于动态库的问题:

    程序运行是加载动态库的几种方法: 第一种,通过ldconfig命令    ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令它,ldconfig命令通 ...

随机推荐

  1. PHP实现JS点击点击定位

    点击class='women' 定位到 class='m=foot'$(".women").on('click',function(){ $("html, body&qu ...

  2. django-celery使用

    1.新进一个django项目 - proj/ - proj/__init__.py - proj/settings.py - proj/urls.py - manage.py 2.在该项目创建一个pr ...

  3. sys模块的介绍

    sys.argv           命令行参数List,第一个元素是程序本身路径 sys.exit(n)        退出程序,正常退出时exit(0) sys.version        获取 ...

  4. oracle 连接字符串的问题

    未指定的错误,发生了一个 Oracle 错误,但无法从 Oracle 中检索错误信息.数据类型不被支持. 原因是你用的ADO   for   ORACLE的驱动是微软的Microsoft OLE DB ...

  5. 使用@FeignClient时,报java.lang.NoClassDefFoundError: feign/Feign$Builder错

    错误信息: Caused by: java.lang.ClassNotFoundException: feign.Feign$Builder at java.net.URLClassLoader.fi ...

  6. Spark 基础之SQL 快速上手

    知识点 SQL 基本概念 SQL Context 的生成和使用 1.6 版本新API:Datasets 常用 Spark SQL 数学和统计函数 SQL 语句 Spark DataFrame 文件保存 ...

  7. Html利用CSS布局技巧

    单列布局水平居中 水平居中的页面布局中最为常见的一种布局形式,多出现于标题,以及内容区域的组织形式,下面介绍四种实现水平居中的方法(注:下面各个实例中实现的是child元素的对齐操作,child元素的 ...

  8. D. Kilani and the Game(多源BFS)

    题目来源:http://codeforces.com/contest/1105/problem/D 题意:编号为1-k的点在一张n*m的表格中依次扩散,每个结点有各自的扩散速度且只可以往上下左右四个方 ...

  9. 227. Basic Calculator II 无括号版本计算器

    [抄题]: Implement a basic calculator to evaluate a simple expression string. The expression string con ...

  10. [leetcode]62. Unique Paths 不同路径

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...