c++11 abi 兼容性
理解 _GLIBCXX_USE_CXX11_ABI: 兼容性与现代化之间的平衡
随着 C++ 标准的不断演进,编译器和标准库实现也在不断更新,以支持新的语言特性和库功能。然而,这些更新有时会引入不兼容的更改,特别是应用程序二进制接口(ABI)的更改。在 GCC 5.1 版本中,引入了新的 C++ 标准库 ABI,这一变化通过 _GLIBCXX_USE_CXX11_ABI 宏进行控制。本文将详细介绍这个宏的作用及其在项目中的使用方法。
什么是 ABI?
ABI(Application Binary Interface)定义了程序二进制接口,包括函数调用约定、参数传递方式、数据结构布局、库函数名称修饰等。ABI 的一致性对于确保编译的二进制文件能够正确链接和运行至关重要。
GCC 5.1 引入的新 ABI
在 GCC 5.1 之前,C++ 标准库使用旧的 ABI。当 GCC 5.1 引入了对 C++11 的更好支持时,同时引入了新的 ABI,这些更改解决了一些长期存在的问题,如改善了 std::string 和 std::list 的实现,但也引入了一些不兼容性。
_GLIBCXX_USE_CXX11_ABI 宏
为了在新旧 ABI 之间提供兼容性,GCC 引入了 _GLIBCXX_USE_CXX11_ABI 宏。这个宏可以在编译时定义,以控制编译器使用哪个 ABI。
_GLIBCXX_USE_CXX11_ABI=0:使用旧的 ABI(GCC 5.1 之前的 ABI)。_GLIBCXX_USE_CXX11_ABI=1:使用新的 ABI(GCC 5.1 及之后的 ABI)。
何时使用 _GLIBCXX_USE_CXX11_ABI
在以下情况下,你可能需要使用 _GLIBCXX_USE_CXX11_ABI 宏:
-
与旧库兼容:如果你的项目依赖于使用旧 ABI 编译的第三方库,你需要使用旧 ABI 来避免链接和运行时的兼容性问题。
-
逐步迁移:如果你正在逐步迁移到新的 ABI,可以使用这个宏在项目的不同部分控制 ABI 的使用,以确保在过渡期间的兼容性。
怎么使用 _GLIBCXX_USE_CXX11_ABI
1、命令行
g++ -D_GLIBCXX_USE_CXX11_ABI=0 xxx.cpp
g++ -D_GLIBCXX_USE_CXX11_ABI=1 xxx.cpp
2、cmake
为一个目标全局指定abi
target_compile_definitions(moduleA PRIVATE _GLIBCXX_USE_CXX11_ABI=0)target_compile_definitions(moduleB PRIVATE _GLIBCXX_USE_CXX11_ABI=1)
单个cpp文件指定不同的abi,可与上面全局指定同时存在
set_source_files_properties(xxx.cpp PROPERTIES COMPILE_DEFINITIONS _GLIBCXX_USE_CXX11_ABI=0)
特殊场景当一个可执行程序同时依赖一个旧ABI库和一个新ABI库时的处理
源码liba.cpp
#include <string>std::string aaaaaaaaaa(){return "this is a";
}
源码libb.cpp
#include <string>std::string bbbbbbbbbb(){return "this is b";
}
使用liba.so的源码a.cpp
#include <string>
#include <iostream>using namespace std;
extern string aaaaaaaaaa();int use_aaaaaaaaaa()
{cout << aaaaaaaaaa() << endl;return 0;
}
使用libb.so的源码b.cpp
#include <string>
#include <iostream>using namespace std;
extern string bbbbbbbbbb();int use_bbbbbbbbbb()
{cout << bbbbbbbbbb() <<endl;return 1;
}
源码main.cpp
#include <string>
#include <iostream>using namespace std;
extern int use_aaaaaaaaaa();
extern int use_bbbbbbbbbb();int main()
{cout << use_aaaaaaaaaa() << endl;cout << use_bbbbbbbbbb() << endl;cout << "hello" << endl;return 0;}
Makefile
all: liba.so libb.so mainliba.so:g++ -D_GLIBCXX_USE_CXX11_ABI=0 liba.cpp -shared -fPIC -o liba.solibb.so:g++ -D_GLIBCXX_USE_CXX11_ABI=1 libb.cpp -shared -fPIC -o libb.somain: main.o a.o b.og++ -o $@ $+ -L. -la -lba.o: a.cppg++ -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC -c -o $@ $<b.o: b.cppg++ -D_GLIBCXX_USE_CXX11_ABI=1 -fPIC -c -o $@ $<main.o: main.cppg++ -D_GLIBCXX_USE_CXX11_ABI=1 -fPIC -c -o $@ $<clean:$(RM) liba.so libb.so main *.otest:LD_LIBRARY_PATH=. ./main
两个so的符号对比

liba.so 使用旧ABI
libb.so 使用新ABI,符号多了cxx11
这两个库不能直接同时在一个cpp中使用,要么用g++4.8编译找不到libb.so里面的bbbbbbbbbb函数定义,要么用g++5.1找不到liba.so里面aaaaaaaaaaa函数定义。究其原因是生成的符号不兼容会无法找到
如果用高于5.1的g++编译,并且
使用liba.so的编译模块a.cpp用-D_GLIBCXX_USE_CXX11_ABI=0编译,且a.cpp不要导出使用了std::string 和std::list的函数
使用libb.so的编译模块b.cpp用-D_GLIBCXX_USE_CXX11_ABI=1编译,且b.cpp不要导出使用了std::string 和std::list的函数
最后编译出来的可执行程序就能兼容两种ABI。
结论
通过使用 _GLIBCXX_USE_CXX11_ABI 宏,你可以灵活地控制项目中不同部分使用的 ABI,从而在保持与旧库兼容的同时,逐步迁移到新的 C++ 标准库 ABI。了解并正确使用这个宏,可以帮助你在项目中平衡现代化与兼容性。
希望本文能帮助你更好地理解和使用 _GLIBCXX_USE_CXX11_ABI 宏,使你的项目在面对 ABI 变化时更加灵活和健壮。
参考链接
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
相关文章:
c++11 abi 兼容性
理解 _GLIBCXX_USE_CXX11_ABI: 兼容性与现代化之间的平衡 随着 C 标准的不断演进,编译器和标准库实现也在不断更新,以支持新的语言特性和库功能。然而,这些更新有时会引入不兼容的更改,特别是应用程序二进制接口(ABI&…...
获取个人免费版Ubuntu Pro
首先上官网地址:Ubuntu Pro | Ubuntu 点击页面中的"Get Ubuntu Pro now" 将用途选为“Myself”,在此页面中Ubuntu说明了该版本只面向个人开发者,且最终只允许5台设备免费使用;因而部署设备的抉择就不得不慎重考虑了&am…...
Pinia的基本用法
Pinia的安装和引入 1.安装Pinia npm install pinia2. 在vue项目的main.js文件中引入pinia import { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst pinia createPinia() const app createApp(App)app.use(pinia) app.mount(#ap…...
正版软件 | DeskScapes:将您的桌面变成生动的画布
您是否厌倦了静态的桌面背景?Stardock 的 DeskScapes 软件赋予您将任何图片或视频动画化的能力,让您的 Windows 桌面焕发活力。 动画桌面,艺术生活 使用 DeskScapes 您可以将任何静态图片或视频转化为桌面背景。不仅如此,通过 60 …...
OpenCV cv::Mat到 Eigen 的正确转换——cv2eigen
在进行计算机视觉项目时,我们经常需要处理相机位姿的变换。最近,我在项目中遇到了一个看似简单但实际上颇具挑战性的问题:从 OpenCV 的 cv::Mat 格式转换到 Eigen 库的格式。这个过程中遇到了一些问题,但最终找到了一个稳健的解决…...
PostgreSQL的扩展(extensions)-常用的扩展-pg_pathman
PostgreSQL的扩展(extensions)-常用的扩展-pg_pathman pg_pathman 是一个用于 PostgreSQL 的分区管理扩展。它提供了一种高效的方式来管理和使用数据库分区,可以显著提升查询性能,特别是在处理大规模数据集时。 安装 pg_pathman…...
数据结构之树
基础知识: 树是一种非线性结构,其严格的数学定义是:如果一组数据中除了第一个节点(第一个节点称为根节点,没有直接前驱节点)之外,其余任意节点有且仅有一个直接前驱,有零个或多个直接…...
6毛钱SOT-23封装28V、400mA 开关升压转换器,LCD偏置电源和白光LED应用芯片TPS61040
SOT-23-5 封装 TPS61040 丝印PHOI 1 特性 • 1.8V 至 6V 输入电压范围 • 可调节输出电压范围高达 28V • 400mA (TPS61040) 和 250mA (TPS61041) 内部开关电流 • 高达 1MHz 的开关频率 • 28μA 典型空载静态电流 • 1A 典型关断电流 • 内部软启动 • 采用 SOT23-5、TSOT23…...
saga模型
Saga源于Hector Garcaa-Molrna和Kenneth Salem发表的论文Sagas。一个LLT事务(Long Lived Transaction)可以分成若干个小的事务执行单元,这些小执行单元就是saga事务。Saga方案更适合用于长事务场景。Saga模型将一个分布式事务拆分为多个本…...
深度神经网络:解锁智能的密钥
深度神经网络:解锁智能的密钥 在人工智能的浩瀚星空中,深度神经网络(Deep Neural Networks, DNNs)无疑是最耀眼的那颗星。它以其强大的学习能力、高度的适应性和广泛的应用场景,成为了我们解锁智能世界的一把密钥。本…...
国际现货黄金最新价格如何分析?结合较高的时间周期
国际现货黄金投资是一种24小时交易的品种,这意味着,在交易日我们打开电脑图表,分析完走势之后就有机会做交易了。但问题也出在这里,如果对国际现货黄金最新价格把握不住,分析和交易就无从谈起了,下面我们就…...
微服务和kafka
一、微服务简介 1.单体架构 分布式--微服务--云原生 传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统一部署,一个进程 all in one的架构方式,把所有的…...
Jetpack架构组件_Navigaiton组件_1.Navigaiton切换Fragment
1.Navigation主要作用 方便管理Fragment (1)方便我们管理Fragment页面的切换 (2)可视化的页面导航图,便于理清页面间的关系。 (3)通过destination和action完成页面间的导航 (4&a…...
[计算机网络] 虚拟局域网
虚拟局域网 VLAN(Virtual Local Area Network,虚拟局域网)是将一个物理的局域网在逻辑上划分成多个广播域的技术。 通过在交换机上配置VLAN,可以实现在同一个VLAN 内的用户可以进行二层互访,而不同VLAN 间的用户被二…...
LabVIEW遇到无法控制国外设备时怎么办
当使用LabVIEW遇到无法控制国外产品的问题时,解决此类问题需要系统化的分析和处理方法。以下是详细的解决思路和具体办法,以及不同方法的分析和比较,包括寻求代理、国外技术支持、国内用过的人请教等内容。 1. 了解产品的通信接口和协议 思路…...
.hmallox勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
导言: 在当今数字化时代,勒索病毒已经成为网络安全的一大威胁,其中包括了最近出现的.hmallox勒索病毒。这类恶意软件不仅能够对计算机系统进行加密,还会要求用户支付赎金以换取解密密钥,给个人用户和企业带来了严重的…...
Redis发布、订阅模式(Pub/Sub)详解
Redis发布、订阅模式(PUB-SUB)详解 Redis的发布订阅(Pub/Sub)机制是一种消息通信模式,用于消息的广播。它允许多个客户端订阅(Subscribe)特定的频道(Channel),…...
Django-开发一个列表页面
需求 基于ListView,创建一个列表视图,用于展示"BookInfo"表的信息要求提供分页提供对书名,作者,描述的查询功能 示例展示: 1. 数据模型 models.py class BookInfo(models.Model):titlemodels.CharField(verbose_name"书名",max_length100)authormode…...
flink 处理函数和流转换
目录 处理函数分类 概览介绍 KeydProcessFunction和ProcessFunction 定时器TimeService 窗口处理函数 多流转换 分流-侧输出流 合流 联合(Uniion) 连接(connect) 广播连接流(BroadcatConnectedStream…...
详细分析Springmvc中的@ModelAttribute基本知识(附Demo)
目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
