如何链接到共享库中定义的 [abi:cxx11] 函数?

Posted

技术标签:

【中文标题】如何链接到共享库中定义的 [abi:cxx11] 函数?【英文标题】:How to link to a function with [abi:cxx11] defined in a shared library? 【发布时间】:2021-12-30 14:12:31 【问题描述】:

我正在使用nm 工具查看共享库。我有这个库的两个版本,在每个版本上,我都有一个重载类型转换的定义,即

版本 1

FrEspinosa@computerLinux:~frameworkPath1/lib $ nm -D libcomm.so | c++过滤器| grep comm::InstanceID::operator

000cda80 T comm::InstanceID::operator std::__cxx11::basic_string

第 2 版

FrEspinosa@computerLinux:~frameworkPath2/lib $ nm -D libcomm.so | c++过滤器| grep comm::InstanceID::operator

00080ead T comm::InstanceID::operator std::__cxx11::basic_string>[abi:cxx11]() const

这是什么>[abi:cxx11],我的函数签名/声明在我的头文件中应该是什么样子,以便它与版本 2 匹配?我需要一个特殊的编译器标志,还是链接一个特殊的库?

作为参考,与版本 1 成功链接的函数如下所示:

namespace comm 

  struct InstanceID
     .
     .
    __attribute__ ((visibility("default"))) operator ipl::string () const;
  

编辑:

作为进一步的参考,我使用的编译器/链接器是

arm-poky-linux-gnueabi-gcc (GCC) 8.2.0

该库是用 GNU 6.2.0 编译的

FrEspinosa@computerLinux:~/frameworkPath2/lib $ strings -a libcomm.so | grep -i gcc

libgcc_s.so.1 GCC_3.5 GCC:(GNU)6.2.0 compilerPath/usr/lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/6.2.0/include

所以我正在使用更新的编译器。

【问题讨论】:

【参考方案1】:

ABI 在 C++11 中发生了变化,这意味着对象的结构,更重要的是它们的大小也发生了变化。为了防止有人链接旧 ABI,编译器开始在对象名称中添加后缀 [abi:cxx11]

这意味着,您正在查看的库是使用较新的编译器编译的,而您使用的是旧式编译器。你需要进入一个新的编译器。

【讨论】:

我使用的编译器比用于库的编译器更新。见编辑。 你能编译这个 sn-p:#include <string> std::string getit() return "Hello"; 使用 g++ -O3 -shared file.cpp -o file.so 然后做 nm -C file.so。你看到T getit[abi:cxx11]()了吗? 我确实看到了T getit[abi:cxx11]()。顺便提一下,我正在使用编辑中显示的交叉编译器... 我用我的交叉编译器试过了,我也看到T getit[abi:cxx11]() 好的 那么哪个库没有呢?那是用旧库编译的库

以上是关于如何链接到共享库中定义的 [abi:cxx11] 函数?的主要内容,如果未能解决你的问题,请参考以下文章

由于符号与 abi::cxx11 的链接问题?

Makefile 报告 `func[abi:cxx11]()' 的多个定义

如何在GDB中调用C ++函数?

如何检测二进制/库中的未定义符号?

强制 GCC 通知共享库中未定义的引用

静态库中的未定义符号链接到动态库