【问题标题】:Linking shared library with libm将共享库与 libm 链接
【发布时间】:2020-08-28 10:08:48
【问题描述】:

我有一个与 libm (动态)链接的程序。 该程序还有几个插件。 插件使用 dlopen() 显式加载。 其中一些插件使用 libm 中的 round()。

在一个系统上(Linux Mint 19.1 gcc 7.5.0)程序 由于未解决的回合而无法工作。

这是一个简单的例子:

  1. 库 (lib.c)

     #include <stdio.h>
     #include <math.h>
    
     void func(double a, double b)
     {
         double c;
         c = round(a + b);
         printf("c = %lf\n", c);
     }
    
  2. 主程序(main.c)

     #include <stdio.h>
     #include <dlfcn.h>
    
     void *dll;
     void (*f)(double, double);
     double a = 1.234, b = 4.321;
    
     int main(void)
     {
         dll = dlopen("./lib.so", RTLD_LAZY);
         f = dlsym(dll, "func");
         f(a,b);
         return 0;
     }
    
  3. 构建(生成文件)

     all:
             gcc -Wall -Os -shared -fPIC lib.c -o lib.so
             gcc -Wall -Os -rdynamic -fPIC main.c -o main -ldl -lm
    
  4. 在 Debian 8、gcc 4.9.2 上运行

      ./main 
     c = 6.000000
    
  5. 在 Linux Mint 19.1、gcc 7.5.0 上运行

      ./main 
     ./main: symbol lookup error: ./lib.so: undefined symbol: round
    

现在,为 dll 编译添加 -lm

    gcc -Wall -Os -shared -fPIC lib.c -o lib.so -lm

     ./main 
    c = 6.000000

那么,问题是 - 为什么在这个特定的系统上必须使用 -lm 不仅用于主程序而且还用于插件?

【问题讨论】:

    标签: c linker shared-libraries


    【解决方案1】:

    就像可执行程序一样,共享库是链接实体(不像静态库是对象文件的存档)。

    由于共享库像可执行文件一样被链接,您还需要与您的库所依赖的库进行链接:

    gcc -Wall -Os -shared -fPIC lib.c -o lib.so -lm
    

    【讨论】:

    • 问题是为什么许多其他系统不需要它 - i386 上的 Debian 6、amd64 上的 Debian 8,9、ARM 上的 Armbian(确切地说是橙色 PI)
    • 检查链接器选项--as-needed的默认设置。无论如何,你应该链接你的库,没有未解析的符号。
    • 主程序链接到libm;由主程序使用 dlopen() 加载的 dll,使用来自 libm 的符号;这些 dll 应该看到这些符号吗?通常他们不会将它们“个人”链接到 libm; Linux Mint 19.1 到底出了什么问题?
    • @dee0xeed 您认为错误的行为实际上是 默认 和标准行为。构建链的其他发行版可能会添加特殊标志来更改此默认行为。共享库和对象应始终作为独立的可执行文件链接(除非使用-shared 标志使它们共享)。
    • “检查链接器选项的默认设置” - 所有系统都“开箱即用”使用,没有进行任何特殊的链接器调整。事实是来自“Linux Mint 19.1”的链接器的行为不同 - 主程序在启动时加载的 libm 中的符号在主程序使用 dlopen() 加载的共享库中看不到
    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多