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. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
