The differences of dynamically link and static link linux so

提起Dynamically linked,则要归结到库的概念和应用了,所以我就系统地了解了一下子,并愿意贴出来,跟大家一起分享。

库的目的是将类似的功能封装在一个单元集中。这些单元可以被其他开发人员共享,并称其为模块化编程,也就是说从模块中编译程序。Linux支持两种类型的库,每种都有自己的优点和缺点。静态库在编译程序时,将库中相应的功能绑定到程序中;然而动态库则不同,它是当程序在运行时才被加载的。图1显示了linux库的层次结构。

图1 linux库的层次结构

你可以通过两种方式来使用共享库的:要么在程序运行时动态地链接,要么在用户的控制下进行动态地加载。这篇文章将讨论着两种方式。

静态库对于功能少的小程序中是有益的。然而对于需要多个库的程序来说,共享库则可以减少程序的内存占用(包括磁盘上的和运行时的内存)。这是因为多个程序可以同时使用一个共享库,因此在一个时间,内存中只需要保留一个共享库的副本即可。使用静态库,每一个正在运行的程序库都有个库的副本。

GNU / Linux提供两种方法来处理共享库(每个方法都是Sun Solaris起源)。你可以动态链接共享库,并在执行时,使用Linux系统加载库(除非它已经在内存中了)。另一种方案是有选择性地调用进程中的库函数,被称为动态加载。采用动态加载,程序可以加载一个特定的库(除非已经加载),然后调用该库中的某一特定功能。 (图2显示了这两种方法。)这是在建立支持插件的应用程序时所共同使用的模式。

图2 动态链接

Linux的动态链接

现在,让我们深入探讨了在Linux中使用动态链接的共享库的过程。当用户启动应用程序时,它们是调用一个可执行的和链接格式(ELF)的镜像。内核始于加载ELF映像到用户空间的虚拟内存的过程。内核注意到一个名为ELF段,被称为.interp,这表明动态链接器要被使用(/lib/ld-linux.so),如清单1所示。这类似于在UNIX中所解释定义的脚本文件(#!/bin/sh):只是在不同的上下文中使用。

注意:ld-linux.so(elf动态库的装载器)

清单1 使用只readelf命令来展示程序的头文件

mtj@camus:~/dl$ readelf -l dl

Elf file type is EXEC (Executable file)

  Entry point 0x8048618

  There are 7 program headers, starting at offset 52

  Program Headers:

  Type           Offset   VirtAddr    PhysAddr   FileSiz MemSiz  Flg Align

  PHDR           0x000034 0x08048034 0x08048034  0x000e0 0x000e0 R E 0x4

  INTERP         0x000114 0x08048114 0x08048114 0x00013  0x00013 R   0x1

  [Requesting program interpreter: /lib/ld-linux.so.2]

  LOAD           0x000000 0x08048000 0x08048000 0x00958  0x00958 R E 0x1000

  LOAD           0x000958 0x08049958 0x08049958  0x00120 0x00128 RW  0x1000

  DYNAMIC        0x00096c 0x0804996c  0x0804996c 0x000d0 0x000d0 RW  0x4

  NOTE           0x000128 0x08048128 0x08048128  0x00020 0x00020 R   0x4

  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000  0x00000 RW  0x4

  ...

  mtj@camus:~dl$

请注意,ld-linux.so本身就是一个ELF共享库,但它是静态编译的,并不依赖于共享库。当需要动态链接时,内核自动启动动态链接器(ELF解释器),它先初始化自身,然后加载指定的共享对象(除非已加载)。之后,它执行必要的再定位,包括目标共享对象所使用的共享对象。 LD_LIBRARY_PATH环境变量定义了可用的共享对象的路径。完成后,控制权转移回原来的程序,开始执行。 

Linxu中的动态加载

其实Linux会为给定的程序自动装载和链接库,它可以分享这个应用程序本身的控制。在这种情况下,这一过程被称为动态加载。有了动态加载,应用程序可以指定一个特定的库来加载,然后将其作为一个可执行库来使用(即调用其中的函数)。然而,正如你前边所学,共享库动态加载功能,只不过是一个标准的共享库(ELF共享对象)。事实上,ld-linux动态链接作为ELF加载器和解释器仍然参与了这项工作的过程。 
动态加载(DL)的API可以动态加载共享库,并允许将其提供给用户空间的程序。API虽然小,但是它提供程序需要的所有东西,并在程序执行背后做了好多工作,完整的API见表1。

表1 完整的API


Function

Description

dlopen

打开一个动态链接库

dlsym

获取所打开文件对象的描述符地址

dlerror

返回最后一次发生错误的信息字符串

dlclose

Closes an object file关闭一个文件对象











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值