c++11 - 链接器找不到符号,但是它们在那里?

标签 c++11 linker symbols

尝试编译此cfgparser example

$ g++ example.cc -lcfgparser
: In function `main':
example.cc:(.text+0x6b): undefined reference to `ConfigParser_t::readFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
example.cc:(.text+0x160): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0x2d9): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int*) const'
example.cc:(.text+0x43c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double*) const'
example.cc:(.text+0x5b1): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool*) const'
example.cc:(.text+0x78c): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*) const'
example.cc:(.text+0xa15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xba2): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xd15): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
example.cc:(.text+0xe7f): undefined reference to `ConfigParser_t::getValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*) const'
collect2: error: ld returned 1 exit statu

但显然这些符号在那里:
$ nm -gC /usr/lib/libcfgparser.so
000000000003710 T ConfigParser_t::readFile(std::string const&)
0000000000004880 T ConfigParser_t::ConfigParser_t(std::string const&)
00000000000024c0 T ConfigParser_t::ConfigParser_t()
0000000000004ad0 T ConfigParser_t::ConfigParser_t(std::string const&)
00000000000024a0 T ConfigParser_t::ConfigParser_t()
0000000000004d20 T ConfigParser_t::getOptions(std::string const&) const
00000000000028d0 T ConfigParser_t::getSections() const
0000000000002ff0 T ConfigParser_t::getValue(std::string, std::string, bool*) const
0000000000002de0 T ConfigParser_t::getValue(std::string, std::string, double*) const
0000000000002bd0 T ConfigParser_t::getValue(std::string, std::string, int*) const
00000000000027d0 T ConfigParser_t::getValue(std::string, std::string, std::string*) const
0000000000003500 T ConfigParser_t::getValue(std::string, std::string, std::vector<std::string, std::allocator<std::string> >*) const

与SO上的其他类似问题不同,这与链接顺序无关,因为仅链接了一个目标文件。我想念的东西吗?

最佳答案

But clearly those symbols are there:



显然,他们不是。仔细看看,您会看到
您的报告的签名之间没有匹配项
链接器未定义,并通过以下方式从库中报告nm

标准 header <string>std::string定义为typedef,用于:
std::basic_string<char, std::char_traits<char>, std::allocator<char>>

cxx11 ABI开始的<string>的GCC实现(GCC 4.7.0)
定义std::string为typedef用于:
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>
std::__cxx11命名空间包含其二进制实现为
符合cxx11 ABI。

该类型定义意味着包含Standard header <string>的C++转换单元将不会
在GCC> = 4.7的情况下,将其编译为目标代码,其中包含分解为std::string的符号。

如果二进制文件(如libcfgparser.so)包含一个符号分解为std::string,则
无论该符号在构建它的源中可能已经引用过,它都不会引用std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>
并且不能与使用std::string定义编译的其他二进制文件链接。

您的libcfgparser.solibcfgparser0_1.1.2_amd64.deb
cfgparser Sourceforce project
(最近更新于三年前)。我从这个事实猜测到
使用与该软件包安装的库链接的相同example.cc程序获取链接错误。

该错误的解释通过以下方式揭示:
/usr/lib$ strings -a libcfgparser.so | grep "GCC: ("
GCC: (Debian 4.3.2-1.1) 4.3.2
...

告诉我们该库是使用GCC 4.3.2构建的-在cxx11 ABI之前。
std::string输出中显示的nm是cxx11之前的分词缩写
std::basic_string<char, std::char_traits<char>, std::allocator<char>>

libcfgparser.so与您当前的GCC不兼容,因此您
无法将其链接到使用该编译器生成的程序。你能做的是
从源代码包libcfgparser构建libcfgparser-1.1.2.tar.bz2
使用当前的编译器,然后将程序与您拥有的库链接
建立自己。

那行得通,但并非毫不费力。首先,您需要修复损坏的
和过时的源代码包自动工具创建有效的./configure脚本。

这并不能使人对包维护者的熟练程度有任何放心的印象。
加上该软件包的源代码(版权为2008),具有业余质量。如果
您需要的是用于INI样式文件的C++解析器,然后 boost::property_tree::ini_parser 将是
转到解决方案。参见this answer

关于c++11 - 链接器找不到符号,但是它们在那里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41134190/

相关文章:

d3.js 符号而不是圆圈

c++ - 如何找到 VC++ v10 中的新增功能?

c++ - 启用 if/else 类成员模板实例化

c++ - std::make_signed 接受浮点类型

c - 编译单元中符号的可见性级别 - C

C# 相当于 Ruby 符号

c++ - 使用 using 捕获模板化可调用对象的返回类型

c++ - 在 C++ 中的 #pragma 注释之前搜索可用的库?

c++ - 为什么链接器找不到静态库中确实存在的符号?

linux - 如何使用linux命令替换tsv文件中的特定符号[如 ' , ^ ,\t'等]?