根据说明文档“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. python 实现统计ftp服务器指定目录下文件夹数目、文件数目及所有文件大小

    本次主要为满足应用方核对上传到ftp服务器的文件是否缺漏. 主要要求:指定目录下,文件夹数目/文件数目/所有文件大小,类似Windows如下功能: 模块介绍: from ftplib import F ...

  2. indexOf() 如何判断一个元素在指定数组中是否存在? 找出指定元素出现的所有位置? indexOf()方法 是正序查找,lastIndexOf()是倒叙查找

    indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1. let a = [2, 9, 7, 8, 9]; a.indexOf(2); // 0 a.indexOf ...

  3. ELK收集Nginx|Tomcat日志

    1.Nginx 日志收集,先安装Nginx cd /usr/local/logstash/config/etc/,创建如下配置文件,代码如下 Nginx.conf input { file { typ ...

  4. Shiro HashedCredentialsMatcher 认证匹配

    Shiro 提供了用于加密密码和验证密码服务的 CredentialsMatcher 接口,而 HashedCredentialsMatcher 正是 CredentialsMatcher 的一个实现 ...

  5. 加入 Jungle Testnet

    [加入 Jungle Testnet] 主网测试需要消耗大量 EOS,JungleTestnet为我们提供了一个测试用的EOS主链,上面的EOS可以通过申请获得.每6小时可以申请100EOS. [创建 ...

  6. java学习笔记(九):Java 流(Stream)、文件(File)和IO

    Java 的控制台输入由 System.in 完成. 为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流.需要import ...

  7. 【转】GT 的性能测试方案解析

    前言 本文将整理腾讯GT各个性能测试项的测试方法,目的是为了帮助移动性能专项测试同学快速过一遍腾讯GT各个性能数据是如何获取的.另外对腾讯GT还不了解或者不知道它能做什么的同学可以看看这篇文章:htt ...

  8. FortiGate日志设置

    1.默认 FGT5HD3916802737 # config log syslogd setting FGT5HD3916802737 (setting) # show config log sysl ...

  9. [leetcode]42. Trapping Rain Water雨水积水问题

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  10. 分布式Snowflake雪花算法

    前言 项目中主键ID生成方式比较多,但是哪种方式更能提高的我们的工作效率.项目质量.代码实用性以及健壮性呢,下面作了一下比较,目前雪花算法的优点还是很明显的. 优缺点比较 UUID(缺点:太长.没法排 ...