Android12之IBinder中[[clang::lto_visibility_public]]作用(一百六十)

news2024/10/7 1:20:49

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解C/C++中,[[clang::lto_visibility_public]]的用法。

class [[clang::lto_visibility_public]] IBinder : public virtual RefBase{};

在IBinder.h中,发现IBinder前边的写法很奇怪,科普下它的作用。

[[clang::lto_visibility_public]]作用:

在C++中,[[clang::lto_visibility_public]]的作用是在链接时优化(LTO)期间指定一个符号应具有公共可见性。
它确保在执行LTO时,链接器不会消除或优化掉该符号。

clang还有其他属性,比如:

  • [[clang::lto_visibility_private]]:用于指定符号在LTO期间应具有私有可见性,确保链接器在LTO期间不会消除或优化该符号。
  • [[clang::lto_visibility_protected]]:用于指定符号在LTO期间应具有受保护的可见性,确保链接器在LTO期间不会消除或优化该符号。
  • [[clang::lto_visibility_hidden]]:用于指定符号在LTO期间应具有隐藏的可见性,确保链接器在LTO期间不会消除或优化该符号。

2.应用实例

<1>v1.0

#include <iostream>
using namespace std;

//[[clang::lto_visibility_public]] void foo() {
//[[clang::lto_visibility_hidden]] void foo() {
//[[clang::lto_visibility_protected]] void foo() {
[[clang::lto_visibility_private]] void foo() {


  printf("xxx---------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

int main() {
    foo();
    return 0;
}

<2>v2.0

1.clang_visitable_02.h

#include <iostream>

[[clang::lto_visibility_private]] void privateFunction();

[[clang::lto_visibility_protected]] void protectedFunction();

[[clang::lto_visibility_hidden]] void hiddenFunction();

[[clang::lto_visibility_public]] void publicFunction();

2.clang_visitable_02.cpp

// - [[clang::lto_visibility_private]]将符号的可见性限制为仅在当前编译单元中可见。
// - [[clang::lto_visibility_protected]]将符号的可见性限制为当前编译单元和其他使用相同链接时可见的编译单元。
// - [[clang::lto_visibility_hidden]]将符号的可见性限制为当前编译单元和其他使用相同链接时可见的编译单元,但不会导出符号。
// - [[clang::lto_visibility_public]]将符号的可见性设置为全局可见,可以在任何编译单元中访问。

#include <iostream>
#include "clang_visitable_02.h"
[[clang::lto_visibility_private]] void privateFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

[[clang::lto_visibility_protected]] void protectedFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

[[clang::lto_visibility_hidden]] void hiddenFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

c void publicFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

3.main.cpp

#include "clang_visitable_02.h"

int main() {
  privateFunction();
  protectedFunction();
  hiddenFunction();
  publicFunction();

  return 0;
}

<3>.编译实验

1.clang++编译选项

1.-fvisibility=hidden: 表示所有符号默认都是不可见的,除非明确标记为可见.
# clang++ -fPIC -shared -o libtest.so -fvisibility=hidden -flto clang_visitable_02.cpp

2.-fvisibility=default:这是默认值,表示所有符号都是可见的.
# clang++ -fPIC -shared -o libtest.so -fvisibility=default -flto clang_visitable_02.cpp

4.-fvisibility=protected:表示所有符号默认都是受保护的,除非明确标记为可见.
# clang++ -fPIC -shared -o libtest.so -fvisibility=protected -flto clang_visitable_02.cpp

2.执行程序

# clang++ main.cpp -L ./ -ltest -o main
# export LD_LIBRARY_PATH=.
# ./main

3.总结

<1>.结论一

发现编译:-fvisibility=hidden、default、protected选项都不会对程序运行造成影响,在-fvisibility=hidden选项的情况下函数都不可被main函数调用,在default、protected选项都可用。

<2>.结论二:IBinder增加[[clang::lto_visibility_public]]的原因

clang 优化中的“ -fwhole-program-vtables ”选项会导致IBinder出现问题。在SurfaceFlinger中,优化使BpBinder对象的行为类似于IBinder,当调用linkToDeath的时候会出问题,应该调用BpBinder的linkToDeath函数,现在却调用了IBinder的linkToDeath函数。当用“ [[clang :: lto_visibility_public]] ”为clang注释IBinder时,将调用适当的linkToDeath函数。

大家可以做实验试下,-fwhole-program-vtables -flto命令如下:

#  clang++ -fPIC -shared -o libtest.so -fwhole-program-vtables  -flto clang_visitable_02.cpp

<3>.结论三

如果想要控制libtest.so中的函数是否能被访问,举个简单的例子

(1).test.cpp:被编译成libtest.so

 void hiddenFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

__attribute ((visibility("default")))   void publicFunction() {
  printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);
}

(2).编译

# clang++ -fPIC -shared -o libtest.so -fvisibility=hidden -flto test.cpp
# clang++ main.cpp -L ./ -ltest -o main

(3). 实验结论

在执行clang++ main.cpp -L ./ -ltest -o main命令,也就是main函数连接libtest.so库时,会 报错,原因是说没有定义hiddenFunction函数,为什么呢?因为它没有显示定义__attribute ((visibility(“default”))) ,它可以在编译-fvisibility=hidden -flto函数不被外界找到,但是定义__attribute ((visibility(“default”)))后,外界仍然可以找到它。
它其实和GNU C的访问情况是一样的,只不过这个使用clang++编译,具体可以参考另一篇文章:
C语言之__attribute__((visibility(“default“)))等gcc flag讲解(六十二)

4.最终结论

<1>. [[clang::lto_visibility_public]]修饰不影响函数是否被隐藏

<2>. 函数是否被隐藏,取决于编译选项命令和函数内部定义。

例如:
1.是否使用 clang++ -fvisibility=hidden -flto编译选项
2.是否在函数中增加如下函数的修饰

__attribute ((visibility("default")))   void publicFunction() {
 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/726957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL自治平台建设的内核原理及实践(上)

总第565篇 2023年 第017篇 本文整理自美团技术沙龙第75期的主题分享《美团数据库攻防演练建设实践》&#xff0c;系超大规模数据库集群保稳系列&#xff08;内含4个议题的PPT及视频&#xff09;的第4篇文章。 本文作者在演讲后根据同学们的反馈&#xff0c;补充了很多技术细节&…

如何绘制「UML类图」

一、UML类图简介 类图以反映类的结构(属性、操作)以及类之间的关系为主要目的&#xff0c;描述了软件系统的结构&#xff0c;是一种静态建模方法。类图用来描述系统中有意义的概念&#xff0c;包括具体的概念、抽象的概念、实现方面的概念等&#xff0c;是对现实世界中事物的抽…

设计模式--------结构型模式

结构型模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低&#xff0c;满足“合成复用原则”…

web 页面布局:(三)position 坐标系布局

web 页面布局&#xff1a;&#xff08;三&#xff09;position 坐标系布局 页面坐标系position 设置fixedrelativeabsolutesticky 应用场景 页面坐标系 因为所有文本内容&#xff0c;是从左向右读&#xff0c;自上而下读&#xff0c;和书写习惯&#xff0c;读书习惯一致&#…

惊呆了!这个银行管理技巧也太厉害了吧

在金融行业&#xff0c;蓄电池监控是一项至关重要的任务。随着金融机构的数字化转型和依赖电力的增加&#xff0c;蓄电池成为保障金融系统正常运行的关键组成部分。 因此&#xff0c;对蓄电池的状态进行监控和维护&#xff0c;确保其高效可靠地工作&#xff0c;对金融行业的稳定…

深度学习06-pytorch从入门到精通

文章目录 概述环境准备安装cuda和cudnn安装pytorch 基础张量定义numpy转换数学函数随机数计算函数矩阵处理函数 自动梯度案例计算图 torchvision模块TransformsDataSetDataLoader自定义数据集 nn模块nn.ModuleCNN图像处理层nn.Conv2dnn.AvgPool2d和nn.MaxPool2dnn.Linearnn.Bat…

TransFuse

方法 Transformer分支 将不同尺度的特征图 t 0 、 t 1 和 t 2 t^0、t^1和t^2 t0、t1和t2保存起来&#xff0c;之后与对应的CNN分支的特征图融合。 CNN分支 以基于ResNet的模型为例&#xff0c;模型通常有五个块&#xff0c;每个块对特征图进行两倍下采样。我们获取第 4( g 0…

vue父组件调用子组件的Form表单校验

需求1&#xff1a;父组件调用子组件的表单验证方法&#xff0c;验证成功&#xff0c;继续进行接下来的操作&#xff0c;验证失败&#xff0c;提示用户并返回。 需求2&#xff1a;父组件校验多个子组件的表单验证方法&#xff0c;验证成功&#xff0c;继续进行接下来的操作&…

cookie/session/token(持续更新)

1.cookie 1.1概念 cookie是服务器产生的保存在客户端的一小段文本信息,格式是字典形式,键值对形式 cookie有两类: 1.会话级cookie:保存在内存,随浏览器关闭自动消息 2.持久化cookie:保存在硬盘,浏览器关闭不会直接消失,生命周期取决于失效时间 1.2如何查看cookie以及格式…

vue3+vite+element pro + pnpm 创建的monorepo项目

vue3+vite+element pro + pnpm 创建的monorepo项目 欢迎使用河码桌面技术说明界面欢迎使用河码桌面 欢迎使用河码桌面,河码桌面是一个基于vue3+vite+element pro + pnpm 创建的monorepo项目,项目采用的是类操作系统的web界面,操作起来简单又方便,符合用户习惯,又没有操作…

GlusterFs部署及使用

目录 一、部署和使用 1. clusterfs服务器初始化 2. 部署glusterfs 3. 创建volume 4. 客户端挂载和使用 5. k8s使用glusterfs作为后端存储&#xff08;静态供给glusterfs存储&#xff09; 5.1 集群所有节点安装glusterfs客户端 5.2 k8s创建资源对象使用glusterfs存储 5.…

Spring Boot 中的声明式事务是什么,如何使用

Spring Boot 中的声明式事务是什么&#xff0c;如何使用 简介 在数据库操作中&#xff0c;事务是一组操作的集合&#xff0c;这些操作在一个逻辑单元内执行&#xff0c;如果其中任何一个操作失败&#xff0c;则整个事务都会被回滚&#xff0c;使得数据库回到事务执行之前的状…

不看产品、不重销售,聊聊Forrester推荐的CLG战略

近日&#xff0c;Forrester的分析师们发现&#xff0c;企业&#xff08;尤其是B2B企业&#xff09;对于CLG战略的关注空前增加。而且&#xff0c;越来越多SaaS企业选择CLG战略来取代以前的PLG&#xff08;产品导向型增长&#xff09;或SLG&#xff08;销售导向型增长&#xff0…

SpringSecurity之基本原理

目录 核心过滤器 FilterSecurityInterceptor ExceptionTranslationFilter UsernamePasswordAuthenticationFilter BasicAuthenticationFilter 过滤器加载过程 重要接口 UserDetailsService接口 PasswordEncoder接口 springSecurity本质上就是一个过滤器链&#xff0c;…

RabbitMQ系列(16)--用SpringBoot整合RabbitMQ

1、新建项目 2、新建Spring项目 3、选择合适的SpringBoot版本&#xff0c;依赖在这里可以先不选&#xff0c;可以在项目生成后在pom.xml文件里批量的导入依赖 4、设置项目的Maven (1)打开设置 (2)在搜索框里输入Maven搜索Maven设置&#xff0c;然后根据自己的实际情况设置Mave…

优化篇--Vue模版语法做动态渲染

Vue模版语法做动态渲染&#xff0c;随便记录一下 <a-row v-for"(row, rowIndex) in footerConfig" :key"rowIndex"><a-col span"4" v-for"(col, colIndex) in row" :key"colIndex"><span class"total-l…

新来的资深java不会lambda表达式,中级开发都笑拉了--lambda流这么难吗,教你怎么玩早学早吃香

因为一个人就全体 虽然没提名字但是说的意思和报身份证没区别, 我自己看着都尴尬… 标题就是事情的经过,和同事的聊天记录在最下面 前言 Lambda表达式是优化代码的工具&#xff0c;使得代码更简洁、易读&#xff0c;符合现代开发的趋势,以及推动函数式编程在Java开发中的流行…

web3创业有哪些机会?(一)

目录 1. 去中心化金融&#xff08;DeFi&#xff09;&#xff1a;2. 去中心化身份验证和数字身份&#xff1a;3. 去中心化市场和电子商务&#xff1a;4. 区块链游戏和虚拟资产&#xff1a;5. 数据隐私和安全&#xff1a;6. 去中心化社交媒体&#xff1a;7. 去中心化能源交易&…

Webpack原理与实战 --- 背景介绍

模块化的演进过程 Stage 1 - 文件划分方式 缺点&#xff1a; 模块直接在全局工作&#xff0c;大量模块成员污染全局作用域&#xff1b;没有私有空间&#xff0c;所有模块内的成员都可以在模块外部被访问或者修改&#xff1b;一旦模块增多&#xff0c;容易产生命名冲突&#…

自动化测试及典型开源的自动化测试工具

目录 前言&#xff1a; 自动化测试 自动化测试的意义 手工测试的局限性 自动化测试带来的好处 自动化测试的前提条件 自动化测试的方法 自动化测试的不足 自动化测试的应用方向 典型开源的自动化测试工具 前言&#xff1a; 自动化测试是一种使用软件工具和脚本来执行…