【问题标题】:Building a lib with the same symbols as another lib构建与另一个库具有相同符号的库
【发布时间】:2016-11-10 11:30:53
【问题描述】:

我想为必须替换另一个库的嵌入式系统构建一个共享库。我试图简单地构建一个具有相同符号的库。当我将原始库与 mylib 进行比较时,会有细微的差别。因此可执行文件在我的假库中找不到这个符号。

假库:

0000000000000c90 g    DF .text  0000000000000098  Base        dbus_pending_call_unref(DBusPendingCall*)

原始库:

0000000000020430 g    DF .text  0000000000000070  Base        dbus_pending_call_unref

如您所见,该函数的参数在原始库中不可见。这可能是可执行文件找不到符号的原因吗?如何使符号中的参数对我的假库不可见?

我使用 objdump -TC 查看符号,并在我的 src 文件中使用 CMake 导出标头导出符号。

【问题讨论】:

  • 可能您是在尝试在不重新编译使用共享库的原始库的情况下执行此操作,因此当您尝试使用假库运行二进制文件时会遇到 ldd 错误或类似错误.您得到的具体错误是什么?
  • 它知道参数类型。建议你用 C++ 忘记了extern "C"。
  • 我得到的错误是:符号查找错误:/usr/lib64/libtest.so: undefined symbol: dbus_pending_call_unref
  • 问题是缺少extern "C"。现在它找到了符号:-)

标签: c++ gcc shared-libraries


【解决方案1】:

您已经指出解决方案是添加extern "C",但就上下文而言,答案如下:

C++ 允许根据输入参数重载函数,因此可以分别定义以下两个函数:

void foo(char *bar);
void foo(const char *bar);

为此,您需要确保这些符号不同,因此符号名称是“mangled”,以便将参数编码为符号名称的一部分。在现代 Linux(和大多数其他现代 Unices)上,这种修饰的约定是 Itanium convention,它以 _Z 开头。 c++filt 软件可用于将这些损坏的符号编码/解码为人类可读的内容。

相反,C 不支持函数重载,因此唯一的函数名(而不是其参数)是符号名的一部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2014-12-11
    相关资源
    最近更新 更多