Linux 编译链接那些事儿(02)C++链接库std::__cxx11::basic_string和std::__1::basic_string链接问题总结

本文主要是介绍Linux 编译链接那些事儿(02)C++链接库std::__cxx11::basic_string和std::__1::basic_string链接问题总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 问题背景说明

在自己的项目源码中引用libeasysqlite.so时编译成功,但运行时遇到问题直接报错,找不到符号 symbol:_ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEi。

2 问题描述和解读

使用c++filt查看符号表中未知的这个符号

$c++filt _ZN3sql5FieldC1ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS_10field_typeEisql::Field::Field(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, sql::field_type, int)

查询到该符号对应的真实函数为:

sql::Field::Field(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, sql::field_type, int)

接下来在使用nm命令查询libeasysqlite.so,看是否有该符号对应的函数。使用nm命令查看,如下所示:

.../data/sqlite/build$ nm -gC libeasysqlite.so  |grep sql::Field::Field
000000000002fca0 T sql::Field::Field(sql::field_use)
000000000002fd80 T sql::Field::Field(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, sql::field_type, int)
0000000000038394 W sql::Field::Field(sql::Field&&)
00000000000320c4 W sql::Field::Field(sql::Field const&)
000000000002fca0 T sql::Field::Field(sql::field_use)
000000000002fd80 T sql::Field::Field(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, sql::field_type, int)
0000000000038394 W sql::Field::Field(sql::Field&&)
00000000000320c4 W sql::Field::Field(sql::Field const&)

这里发现并没有我们需要的sql::Field::Field(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, sql::field_type, int)方法,而是有一个类似的sql::Field::Field(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, sql::field_type, int)方法,这就说明有可能是编译时使用的链接库不同而导致的问题。

这里是cxx11空间,对应的是 C++11版本的链接库,而我们需要的是__1空间的库,也就是C++03版本的链接库。那么如何修改呢?就是在CMakeList.txt文件中添加一些参数,如下所示:

set(CMAKE_CXX_COMPILER clang++-14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")

重新编译libeasysqlite.so库。这样在编译生成库的时候就会强制使用C++03版本的标准了,再次make编译出sql库即可。

接下来开始测试该库。修改后执行nm命令查看,如下所示:

.../data/sqlite/build$ nm -gC libeasysqlite.so  |grep sql::Field::Field
00000000000244b0 T sql::Field::Field(sql::field_use)
0000000000024590 T sql::Field::Field(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, sql::field_type, int)
00000000000244b0 T sql::Field::Field(sql::field_use)
0000000000024590 T sql::Field::Field(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, sql::field_type, int)
0000000000029e54 W sql::Field::Field(sql::Field&&)
000000000002734c W sql::Field::Field(sql::Field const&)

这样就和我们需要的对上了。

3 问题总结

该类问题的解决步骤如下所示:

  1. 遇到这类问题时基本上都是使用c++filt来将符号表中的符号转换。
  2. 确认符号是否在库中,如果不在库中那么可能是链接库的版本或者编译方式不对。
  3. 修正编译方式/库的版本,确认符号表中的符号可以对上。接下来进行实测即可。

这篇关于Linux 编译链接那些事儿(02)C++链接库std::__cxx11::basic_string和std::__1::basic_string链接问题总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/343548

相关文章

linux hostname设置全过程

《linuxhostname设置全过程》:本文主要介绍linuxhostname设置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录查询hostname设置步骤其它相关点hostid/etc/hostsEDChina编程A工具license破解注意事项总结以RHE

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素