Linux下gcc编译控制动态库导出函数小结
根据说明文档“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编译控制动态库导出函数小结的更多相关文章
- linux下 GCC编译链接静态库&动态库
静态库 有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 ...
- Linux 下 GCC 编译共享库控制导出函数的方法
通过一些实际项目的开发,发现这样一个现象,在 Windows 下可以通过指定 __declspec(dllexport) 定义来控制 DLL(动态链接库)中哪些函数可以导出,暴露给其他程序链接使用,哪 ...
- C++ 动态库导出函数名“乱码”及解决
C++ 动态库导出函数名“乱码”及解决 刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都“乱码”了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // ...
- 【图文】[新手]C++ 动态库导出函数名“乱码”及解决
刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...
- linux下gcc编译的参数详细说明
参考网址:1 http://hi.baidu.com/zengzhaonong/item/f1f9383565fa5c302e0f8125 gcc使用方法 汇总 2 http://s99f.blog. ...
- Linux环境g++编译GDAL动态库
一.编译步骤 解压下载的GDAL源程序,并在命令行中切换到解压目录. tar -xzvf gdal-2.1.3.tar.gz cd gdal-2.1.3 GDAL可通过configure来实现一些自定 ...
- linux下gcc编译多个源文件、gdb的使用方法
一. gcc常用编译命令选项 假设源程序文件名为test.c. 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理.汇编.编译并链接形成可执行文件.这里未指定输出文件,默认 ...
- Linux环境g++编译TinyXML动态库
除了CMarkup,tinyxml也是C/C++下解析XML很好的工具.在linux下用g++编译tinyxml的步骤如下(tinyxml版本2.6.2): 进入tinyxml解压目录,用文本编辑器打 ...
- linux下,一些关于动态库的问题:
程序运行是加载动态库的几种方法: 第一种,通过ldconfig命令 ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令它,ldconfig命令通 ...
随机推荐
- laravel代码生成器的记录
在使用laravel5.5时,关于代码生成器还有很多的功能不明白 是么回事,在此先记录下来过程. 1.composer reqiure summerblue/generator --dev php a ...
- rpc调用过程
在openstack中,各个组件之间的调用遵循RESTful风格,而组件内部各服务之间的相互调用采用rpc远程调用,比如nova-conductor和nova-compute rpc原理: 首先了解什 ...
- py库: GUI(tkinter)
图形用户界面(Graphical User Interface,简称 GUI) http://www.runoob.com/python/python-gui-tkinter.html Python ...
- 开源项目初涉(C++自我学习开始)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://i.cnblogs.com/EditPosts.aspx?postid=8428885 临近2018农历新年,我还在上班,哈哈. ...
- py目录
Python开发[第二篇]:初识Python Python开发[第三篇]:Python基本数据类型 Python开发[第四篇]:Python基础之函数 &&[4.1]算法递归 冒泡 ...
- MySQL的show profile(已过时)简介以及该功能在MySQL 5.7中performance_schema中的替代
本文出处:http://www.cnblogs.com/wy123/p/6979499.html show profile 命令用于跟踪执行过的sql语句的资源消耗信息,可以帮助查看sql语句的执行情 ...
- MFC---关于string.h相关函数
1.在VS2005中使用strcpy.strcat.sprintf出现如:mfc中'strcpy' was declared deprecated警告 这是因为VS2005中认为CRT中的一组函数如果 ...
- 阿里巴巴Java开发手册与自己开发对照笔记
一编程规约 (一)命名风格 某些时候在命名常量的时候,会觉得太长而减少长度导致命名不清. 抽象类及测试类写得比较少. 这一点值得注意,在开发中,布尔变量我都是使用is开始. 关于包名和类名的单数和复数 ...
- mysql学习笔记--表操作
一.显示所有表 1. 语法:show tables; 二.创建表 1. 语法:create table [if not exists] 表名( 字段名 数据类型 [null | not null] ...
- ES6 Number
1. 新增Number.EPSILON(误差检查函数)