[转]GCC系列: __attribute__((visibility("")))
在 objc-api.h 里面有很多关于__attribute__ 的定义.
例如
#if !defined(OBJC_VISIBLE)
# if TARGET_OS_WIN32
# if defined(BUILDING_OBJC)
# define OBJC_VISIBLE __declspec(dllexport)
# else
# define OBJC_VISIBLE __declspec(dllimport)
# endif
# else
# define OBJC_VISIBLE __attribute__((visibility("default")))
# endif
#endif
可以看到
OBJC_VISIBLE 的定义方式是 __attribute__((visibility("default"))).
那么究竟有什么作用呢? 下面举例说明.
GCC 有个visibility属性, 该属性是说, 启用这个属性:
1. 当-fvisibility=hidden时
动态库中的函数默认是被隐藏的即 hidden. 除非显示声明为__attribute__((visibility("default"))).
2. 当-fvisibility=default时
动态库中的函数默认是可见的.除非显示声明为__attribute__((visibility("hidden"))).
特别说明: 这个特性是 GCC4.0 以后才有的.
基于GCC系列: 加载静态链接库的例子, 谈谈 visibility.
Car.c
#include<stdio.h>
#include<stdlib.h> __attribute ((visibility("default"))) int drive()
{
printf("Car driving...\n"); return ;
} void stop()
{
printf("Car stop.\n");
}
注意: attribute 的定义和使用方法.
使用 visibility 属性来编译动态链接库.
g++-4.9 -shared -o libCar.so -fvisibility=hidden Car.c
这样一来, drive 方法是可见的, 但是 stop 是不可见的.
main.c
#include<stdio.h>
#include<stdlib.h> //
// 在 gcc 编译器下, 必须声明方法
// 在 clang 编译下, 只是给了警告
// int drive();
void stop(); int main()
{
drive();
stop(); return ;
}
编译
g++-4.9 -o app main.c -L ./ -lCar
提示信息
Undefined symbols for architecture x86_64:
"stop()", referenced from:
_main in ccZnwENu.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned exit status
这说明了上面提到的第一中情况.
重新编译 Car.c, 换个方式
g++-4.9 -shared -o libCar.so -fvisibility=default Car.c
注意: 这次使用了 default 属性.
编译 main.c
g++-4.9 -o app main.c -L ./ -lCar
编译成功, 运行 app
./app
Car driving...
Car stop.
那么修改一下 Car.c 的代码
#include<stdio.h>
#include<stdlib.h> __attribute ((visibility("default"))) int drive()
{
printf("Car driving...\n"); return ;
} __attribute ((visibility("hidden"))) void stop()
{
printf("Car stop.\n");
}
使用 visibility=default 和 visibility=hidden 分别编译 Car.c.
可以知道, stop 函数都是隐藏的.
这个也很好的说明了上面两个问题.
注意: g++-4.9 改为 gcc-4.9也是一样的.
另外, 除了 default 和 hidden, 还有 internal, protected.请关注后续讨论.
[转]GCC系列: __attribute__((visibility("")))的更多相关文章
- GCC扩展 __attribute__ ((visibility("hidden")))
试想这样的情景,程序调用某函数A,A函数存在于两个动态链接库liba.so,libb.so中,并且程序执行需要链接这两个库,此时程序调用的A函数到底是来自于a还是b呢? 这取决于链接时的顺序,比如先链 ...
- GCC的__attribute__ ((constructor))和__attribute__ ((destructor))
通过一个简单的例子介绍一下gcc的__attribute__ ((constructor))属性的作用.gcc允许为函数设置__attribute__ ((constructor))和__attrib ...
- 利用gcc的__attribute__编译属性section子项构建初始化函数表【转】
转自:https://my.oschina.net/u/180497/blog/177206 gcc的__attribute__编译属性有很多子项,用于改变作用对象的特性.这里讨论section子项的 ...
- IOS UIKIT_EXTERN, __attribute__((visibility ("default"))) 是啥玩意?
问题提出 在学习IOS时候,碰到一个函数NSStringFromCGPoint (UIGeometry.h) 其原型是 UIKIT_EXTERN NSString *NSStringFromCGPoi ...
- 从gcc的__attribute__((packed))聊到结构体大小的问题
公司的前辈的代码里面 结构体的花括号最后 有__attribute__((packed))字样.以前没见过,所以查了查.学习学习http://blog.sina.com.cn/s/blog_559f6 ...
- gcc之__attribute__简介及对齐参数介绍
GNU C的一大特色就是__attribute__机制.__attribute__机制可以设置函数属性(Function Attribute).变量属性(Variable Attribute)和类型属 ...
- gcc中__attribute__ ((constructor(101)))做成.a库成功链接
1.cpp:------------------------------------------------ #include int test() __attribute__ ((construct ...
- 利用gcc的__attribute__编译属性section子项构建初始化函数表
参考链接 : https://my.oschina.net/u/180497/blog/177206
- gcc __attribute__关键字举例之visibility【转】
转自:https://blog.csdn.net/starstarstone/article/details/7493144?utm_source=tuicool&utm_medium=ref ...
随机推荐
- A01-java学习环境准备
1, 需要去oracle官网下载,JDK https://www.oracle.com/technetwork/java/javase/downloads/index.html 点击SE Do ...
- jQuery笔记(二)
$()下的常用方法 addClass():添加样式 removeClass():删除样式 $('div').addClass('box2 box4'); $('div').removeClass('b ...
- <转>HTML、CSS、font-family:中文字体的英文名称
宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 PMingLiU 细明体 Ming ...
- PAT 甲级 1079 Total Sales of Supply Chain
https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560 A supply chain is a ne ...
- composer 使用(踩坑笔记)
composer的介绍 来张图就好啦!我不细说啦 安装composer 1).PHP 环境变量配置,可参考百度经验: 2).详情可参考中国全量镜像进行 Composer 的安装 3).安装完成后,命令 ...
- Zoom 会议系统
Jfrog的培训过程中 发现ppt的效果很不理想 讲师使用zoom的方式效果很好 首先说一下 zoom的定价体系 官网信息: https://www.zoom.us/profile 好像必须使用 企 ...
- Android控件第1类——TextView
Android提供TextView,它不能被编辑,它的子类EditText可以编辑.TextView有很多子类. 1.EditText,继承自TextView EditText可以编辑. 可以设置in ...
- Android DatePickerDialog和TimePickerDialog显示样式
可以用DatePickerDialog显示选取日期的对话框.可以设置显示的样式 1.通过构造方法设置显示样式. 可以通过DatePickerDialog(Context context, int th ...
- JS 中的require 和 import 区别
这两个都是为了JS模块化编程使用. 遵循规范 require 是 AMD规范引入方式 import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法 调用时间 require是运行时调 ...
- Java结束线程的三种方法(爱奇艺面试)
线程属于一次性消耗品,在执行完run()方法之后线程便会正常结束了,线程结束后便会销毁,不能再次start,只能重新建立新的线程对象,但有时run()方法是永远不会结束的.例如在程序中使用线程进行So ...