1 动态库与静态库的制作与使用

        在 Linux 应用层开发中,当工程规模不断增大、多个程序需要复用相同功能模块时,如果仍然以源文件的方式进行编译和链接,不仅效率低下,也不利于代码管理。为了解决这一问题,Linux 提供了 库(Library)机制,将通用功能封装为库文件,供不同程序重复使用。

        Linux 下常见的库主要分为两类:

  • 动态库(Shared Library)
  • 静态库(Static Library)

1.1 静态库与动态库的基本概念

1.1.1 静态库(.a)
文件后缀:.a
在>>链接阶段<<被完整复制到可执行文件中
程序运行时 不再依赖库文件

📌 特点:

  • 可执行文件体积较大
  • 程序部署简单
  • 不需要额外的库文件
1.1.2 动态库(.so)
文件后缀:.so
在>>运行时<<被加载
可执行文件中只保存符号引用

    📌 特点:

    • 可执行文件体积小
    • 多个程序可共享同一库
    • 运行时必须能找到对应的 .so 文件

    1.2 实际案例工程结构

            以下示例工程用于演示静态库和动态库的制作与使用,创建一个test文件夹,分别存放main.c、sub2.c、sub.c、sub.h文件,其文件目录结构与文件相关代码如下所示:

    test/
    ├── main.c
    ├── sub.c
    ├── sub2.c
    ├── sub.h
    

            ① sub.h文件代码:

    #ifndef _SUB_H_
    #define _SUB_H_
    
    void sub_func(void);
    void sub2_func(void);
    
    #endif
    

            ② sub.c文件代码:

    #include <stdio.h>
    #include "sub.h"
    
    void sub_func(void)
    {
        printf("This is sub_func.\n");
    }
    

            ③ sub2.c文件代码:

    #include <stdio.h>
    #include "sub.h"
    
    void sub2_func(void)
    {
        printf("This is sub2_func.\n");
    }
    

            ④ main.c文件代码:

    #include <stdio.h>
    #include "sub.h"
    
    int main(void)
    {
        sub_func();
        sub2_func();
        return 0;
    }
    

    1.3 动态库的制作与使用

    1.3.1 编译生成目标文件(位置无关代码)

            生成动态库时,必须使用 -fPIC 选项

    gcc -fPIC -c sub.c
    gcc -fPIC -c sub2.c
    
    1.3.2 生成动态库文件
    >>gcc -shared -o libsub.so sub.o sub2.o
    >>生成文件:libsub.so

    1.3.3 使用动态库链接程序
    gcc -o test main.c -L . -lsub
    

    📌 说明:

    • -L .:指定库所在目录
    • -lsub:链接 libsub.so

    1.3.4 运行动态库程序

    方法一:拷贝到系统库目录(不推荐

    sudo cp libsub.so /lib
    ./test
    

    方法二:使用 LD_LIBRARY_PATH(推荐

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
    ./test
    

    1.3.5 查看动态库依赖关系
    ldd test
    

    输出示例:

    1.4 静态库的制作与使用

    1.4.1 编译生成目标文件
    gcc -c sub.c
    gcc -c sub2.c
    
    1.4.2 使用 ar 工具生成静态库
    ar crs libsub.a sub.o sub2.o
    

    1.4.3 使用静态库链接程序
    gcc -o test main.c libsub.a
    

    📌 若静态库不在当前目录,需要指定路径:

    gcc -o test main.c ./lib/libsub.a
    

    1.4.4 运行程序
    ./test
    

    📌 静态库在运行时不需要再拷贝到系统中

    1.5 动态库与静态库对比总结

    对比项 动态库 静态库
    文件后缀 .so .a
    链接时机 运行时 编译时
    可执行文件大小
    运行依赖 需要 .so 不需要
    共享性
    更新方式 替换库即可 需重新编译

    1.6 交叉编译环境下的库制作

            在 ARM 平台下,只需将 gcc 替换为交叉编译器即可:

    arm-buildroot-linux-gnueabihf-gcc -fPIC -c sub.c
    arm-buildroot-linux-gnueabihf-gcc -shared -o libsub.so sub.o
    

    📌 注意

    • 交叉编译动态库时 必须加 -fPIC
    • 运行时 ARM 板上也要能找到对应的 .so

    1.7 本节小结

            本节系统介绍了 Linux 下:

    • 动态库与静态库的基本概念
    • 动态库和静态库的制作流程
    • 程序链接与运行方法
    • 动态库运行时常见问题
    • x86 与 ARM 交叉编译环境下的库使用差异
    Logo

    汇聚全球AI编程工具,助力开发者即刻编程。

    更多推荐