【问题标题】:Regarding Static and Shared Libraries Linking in C关于 C 中的静态和共享库链接
【发布时间】:2014-02-08 20:08:05
【问题描述】:
  #include <stdio.h>

  int main()
  {
          printf("%s","Hello world");
          return 0;      
  }

  $gcc -o hello hello.c

问题:

1 - 我相信 printf 函数的目标文件是静态链接的。对吗?

2 - 我应该如何配置/编写此代码以便动态链接库文件,或者我的意思是它在运行时使用共享库?

注意:我是这个概念的初学者,所以请随时纠正我没有意义的地方

【问题讨论】:

    标签: c linker


    【解决方案1】:

    链接器获取它找到的任何东西。这通常是共享库。

    在Linux系统上,你可以使用

    file hello
    

    找出是静态链接还是动态链接。

    例如

    file /bin/bash
    

    给了

    /bin/bash:ELF 64 位 LSB 可执行文件,x86-64,版本 1 (SYSV),动态链接(使用共享库),适用于 GNU/Linux 2.6.24,BuildID[ sha1]=0x6dafe33f9353cbb054b1b1f7b079545992575757,剥离

    file /bin/busybox
    

    给了

    /bin/busybox:ELF 64 位 LSB 可执行文件,x86-64,版本 1 (SYSV),静态链接,适用于 GNU/Linux 2.6.24,BuildID[sha1]=0xac4943b7daf7c3c204a2866ea5398f2337ff93c9,剥离

    您可以通过在 gcc 中添加 -static 选项来强制建立静态链接

    gcc -static -o hello hello.c
    
    file hello
    

    /tmp/hello:ELF 64 位 LSB 可执行文件,x86-64,版本 1 (GNU/Linux),静态链接,适用于 GNU/Linux 2.6.24,BuildID[sha1]= 0x790ec9b287fd2a276162560e5e6669ba6b73e68f,未剥离

    更新:

    链接是将对象文件、动态和静态库以及一些样板对象放在一起,形成二进制可执行文件的过程。

    您可以在一个可执行文件中同时使用动态库和静态库。静态库所需的目标文件被复制到可执行文件中。另一方面,动态库(实际上是动态对象)不会被复制,而是被生成的二进制文件引用。

    更新:

    库有两种,静态库(ar档案,见man ar

    file /usr/lib/libnet.a
    
    /usr/lib/libnet.a: current ar archive
    

    和动态库(动态对象)

    file /usr/lib/libnet.so.1.5.0 
    
    /usr/lib/libnet.so.1.5.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x0c596357947e79001025b3c57be933690085dffb, stripped
    

    您可以同时安装两种类型的库,例如

    ls -l /usr/lib/libnet.*
    
    -rw-r--r-- 1 root root 207780 Okt 28  2011 /usr/lib/libnet.a
    -rw-r--r-- 1 root root    802 Okt 28  2011 /usr/lib/libnet.la
    lrwxrwxrwx 1 root root     15 Okt 28  2011 /usr/lib/libnet.so -> libnet.so.1.5.0
    lrwxrwxrwx 1 root root     15 Okt 28  2011 /usr/lib/libnet.so.1 -> libnet.so.1.5.0
    -rw-r--r-- 1 root root  92712 Okt 28  2011 /usr/lib/libnet.so.1.5.0
    

    ar 存档包含一个或多个目标文件,如果可执行文件需要,链接器会选择这些目标文件。共享对象是具有子程序的对象,它允许在运行时被其他共享对象或可执行文件调用。

    如果您对此主题感兴趣,还可以查看这篇Wikipedia - Library (computing) 文章。

    【讨论】:

    • 编译后链接器不做它的工作,即它应该是动态的吗? (只是为了好奇)。
    • 是的,首先编译器创建目标文件,然后链接器创建二进制文件。
    • 那为什么经常出现静态链接这个词呢?
    • 我会说,这本身就是一个问题,而不是评论,不是吗? ;-) 无论如何,请参阅更新的答案。我希望这能让它更清楚一点。
    • @hacks “链接器在编译后不做它的工作” - 是的。 “即,它应该是动态的” - 不,为什么?没有关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 2010-11-17
    相关资源
    最近更新 更多