动态库静态库的制作过程

1、动态库静态库的概念

动态库和静态库是在软件开发中常见的库文件类型,用于存储可重用的代码和资源,以便在程序中进行调用。

静态库(Static Library): 静态库是一组预编译的目标文件(通常是 .lib 文件),其中包含了一组函数和数据,可以被链接到程序中。静态库在编译时将库中的代码复制到最终可执行文件中,因此可执行文件比较大。每次程序被编译时,静态库都会被复制到最终的可执行文件中,因此可以在不同的环境中运行。

动态库(Dynamic Library): 动态库是一组已被编译成共享对象文件(通常是 .dll 文件,在 Windows 系统中)的代码和资源,可以在运行时被程序动态加载和链接,也就是说,动态库的代码在程序运行时才被载入内存,不会在编译时被复制到可执行文件中。这使得可执行文件较小,但在程序运行时需要确保系统能够找到动态库。

区别

  • 静态库在编译时被链接到可执行文件中,程序运行时不再需要库文件,但会使得可执行文件变大。
  • 动态库在程序运行时才被加载,可以被多个程序共享使用,节省内存空间,但需要确保系统能找到对应的库文件。

在选择使用动态库还是静态库时,需要考虑项目的需求、平台的支持、便捷性等因素。

2、程序的编译过程

  • 程序在编译时分为多个阶段:
    • 预处理
      • 处理所有预处理命名,包括宏定义、条件编译指令、文件包含指令
    • 编译
      • 进行词法分析、语法分析、语义分析后,将代码翻译成汇编指令
    • 汇编
      • 将汇编指令翻译成机器指令,也就是二进制,形成目标文件
    • 链接
      • 将多个目标文件进行链接,得到一个程序最后的执行文件

 

编译过程演示

预处理:

gcc -E main.c -o main.i

编译:

gcc -S main.i -o main.s

汇编:

gcc -c main.s -o main.o

链接:

gcc  main.o -o main

3、静态库

静态库的文件格式

  • 静态库是函数库二进制文件的一种形式,在 windows 与 Linux 下对应的文件类型
    • Windows :name.lib
    • Linux: libname.a

静态库的特点

  • 静态库的特点:
    • 当编译器链接静态库的时候,如果在可执行文件中有调用静态库的函数接口,则会将静态拷贝到可执行文件中
    • 由于可执行文件中有静态库中函数接口的实现代码,运行的时候不需要静态库
    • 由于链接的时候,需要将库函数接口实现代码拷贝到可执行文件中,所以生成

静态库的制作

  • 静态库的制作:
    • 将 file.c 编译成 file.o
gcc -c main.c -o main.o
  • 将 file.o 生成静态库
ar -rs main.a main.o

 生成静态库main.a

  • ar 命令用于制作静态库的命令,可以使用一些常用的选项

    • -s:将目标文件的索引符号添加到库中
    • -r : 在库中更新文件或者添加新的文件
  • 静态库在链接使用时需要指定头文件的位置与静态库的位置

    • -I : 指定头文件
    • -L: 指定库的位置
    • -l : 指定链接的库的名字

gcc -I<头文件路径> -L<库的路径> -l<静态库的名字> -o <可执行文件名>

  • gcc 编译器默认搜索头文件与库文件的路径
    • /usr/include 为头文件默认路径
    • /usr/lib 与 /lib 为库的默认路径

静态库的优点与缺点

  • 优点

    • 可执行程序在执行的时候,不需要加载动态库,可以直接运行
  • 缺点

    • 多个程序链接静态库的时候,需要拷贝多份静态库的代码,占用的内存较多

4、动态库

动态库的文件格式

  • 动态库的文件格式如下:

动态库的特点

  • 当编译器链接动态库的时候,会在可执行文件的头信息中记录库的名字,便于在操作系统执行这个可执,让操作系统去加载对应的动态库。
  • 当操作系统执行可执行文件时候,会先读取可执行文件的头信息,然后加载头信息中记录的动态库到内存中运行
  • 当可执行文件调用动态库中的函数时,则需要加载动态库到内存中

动态库的制作

  • 动态库的制作过程如下:
  • 将 file.c 编译成 file.o
gcc -c file.c -o file.o
  • 将 file.o 生成动态库
​gcc -shared file.o -o libfile.so

动态库的链接

  • 动态库库在链接使用时需要指定头文件的位置与动态库库的位置
    • -I : 指定头文件
    • -L: 指定库的位置
    • -l : 指定链接的库的名字

gcc -I<头文件路径> -L<库的路径> -l<动态库的名字> <源文件>-o <可执行文件名>

  • gcc 编译器默认搜索头文件与库文件的路径

    • /usr/include 为头文件默认路径
    • /usr/lib 与 /lib 为库的默认路径
  • 与静态库不同的是 动态库在链接成功之后,还需要加载动态库到内存中,编译与加载是两个不同的动作

    • 编译器在编译时并没有将动态库中的函数拷贝到可执行程序中,只是记录动态库的名字
    • 在程序运行调用时,则需要将动态库加载到内存中
    • 动态库默认加载动态库的路径与链接动态库的默认路径是相同的,都是 /lib 与 /usr/lib
    • 当默认路径下没有时,则会到 LD_LIBRARY_PATH 环境变量下去找
    • 可以通过 LD_LIBRARY_PATH 来设置动态库的路径

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:自己库所在的路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值