Linux IO编程——静态库、动态库

一、静态库

(一)静态库的介绍

静态库是在程序编译链接阶段 ,其代码会被完整地**"复制"到最终生成的可执行文件** 中,成为可执行文件的一部分,编译完成后,静态库与可执行文件"绑定",运行时无需额外依赖

特点:可执行文件独立运行,不依赖外部库文件;静态库会使可执行文件体积较大,但是效率比较高;若静态库更新,需重新编译链接程序;

静态库文件格式:windows平台下为**.lib** ;Linux平台下为**.a**;Mac平台下为.a;

(二)静态库制作及使用

准备源文件:编写实现库功能的源文件(如 .c或 .cpp);

编译生成目标文件:将源文件编译成目标文件(如 .o或.obj)gcc -c 源文件.c -o 目标文件.o

bash 复制代码
gcc -c add.c -o add.o

打包生成静态库:使用归档工具将目标文件打包成静态库ar -cr 静态库.a 目标文件.o

bash 复制代码
ar -cr libmyadd.a add.o

编译主程序并链接静态库,生成可执行文件gcc 目标文件.o -l库名 -L库路径 -o 可执行文件

cpp 复制代码
gcc main.c -lmyadd -L. -o main

说明:如果库名是libmyadd.a,则库名是myadd,编译器会自动拼接lib前缀和.a后缀进行查找库文件

bash 复制代码
./main

二、动态库

(一)动态库的定义

动态库也称之为共享库,是在程序运行时才被加载到内存 中,可以被多个可执行文件共享使用,为它们提供函数、数据等资源。

特点:可执行文件运行时,需依赖系统中存在的动态库;可执行文件体积小,有效节省磁盘和内存空间;更新灵活 ,只要接口不变,无需重新编译依赖它的可执行文件;

动态库文件格式:windows平台下为.dll;Linux平台下为.so;Mac平台下为.dylib;

(二)动态库的制作

准备源文件:编写实现库功能的源文件(如 .c或 .cpp);

编译生成与位置无关的目标文件 :使用编译器编译源文件时,添加相关选项(如GCC的-fPIC选项)生成位置无关代码(PIC)的目标文件;gcc -c -fPIC 源文件.c -o 目标文件.o

bash 复制代码
gcc -c -fPIC sub.c -o sub.o

链接生成动态库 :使用编译器将目标文件链接为动态库,多个程序可共享同一份动态库文件,节省内存;gcc -shared 目标文件.o -o 动态库.so

cpp 复制代码
gcc -shared sub.o -o libmysub.so

编译时通过 -L指定路径 、 -l指定库名 生成可执行文件;gcc 源文件.c -l库名 -L库路径 -o 可执行文件

bash 复制代码
gcc main.c -lmysub -L -o my_sub

运行时需通过 LD_LIBRARY_PATH 环境变量、 /etc/ld.so.conf 配置或系统路径,保证动态库可被加载

  • 示例1:通过LD_LIBRARY_PATH环境变量运行export LD_LIBRARY_PATH=$PWD (=后面就是库路径,PWD表示当前路径)

    bash 复制代码
    export LD_LIBRARY_PATH=$PWD
  • 示例2:通过**/etc/ld.so.conf 配置运行** ;编辑配置文件添加动态库路径:
    sudo vim /etc/ld.so.conf (在此文件中添加动态库路径)

    bash 复制代码
    pwd  #查看当前的绝对目录:/home/hqyj/IO/dynamic_library
    sudo vim /etc/ld.so.conf  #进入/etc/ld.so.conf,将当前路径加入


    添加完成之后,执行sudo ldconfig命令更新系统缓存

    bash 复制代码
    sudo ldconfig
  • 示例3:通过系统路径运行:优先考虑/usr/local/lib路径,然后进行更新系统缓存系统级库放/usr/lib,用户自定义库放 /usr/local/lib;

bash 复制代码
sudo mv libmysub.so /usr/local/lib
sudo ldconfig  #更新

三、静态库与动态库的区别

(1)链接方式:静态库在编译时链接,动态库在运行时链接

(2)可执行文件体积:静态库使可执行文件体积大,动态库使可执行文件体积小

(3)内存占用:多个程序使用同一静态库 时,每个程序都有一份库的副本 ,占用内存多 ;多个程序共享同一动态库 时,内存中只有一份库的副本,节省内存

(4)更新维护:静态库更新需重新编译链接程序动态库更新只需替换库文件,无需重新编译链接程序;

(5)依赖性:静态库无运行时依赖;动态库有运行时依赖,库缺失程序无法运行

(6)适用场景:

  • 静态库:适合对程序独立性要求高,库不常更新,且对可执行文件启动速度有要求的场景;
  • 动态库:适合库需要频繁更新多个程序共享库功能,且希望减小可执行文件体积的场景;

四、库制作常见问题及解决方案

(一)静态库链接时提示未定义的引用

可能原因:库文件路径错误、库名拼写错误、库中确实不存在该函数或变量的定义;

解决方法:检查库路径和库名是否正确,确认库中是否实现了所需功能;

(二)动态库运行时提示无法找到库文件

可能原因:库文件路径未加入系统默认搜索路径或者是未通过环境变量指定;

解决方法:将动态库复制到系统默认库路径(如/usr/local/lib),或设置相应的环境变量(如Linux的LD_LIBRARY_PATH);

(三)动态库版本冲突

可能原因:程序依赖的动态库版本与系统中安装的版本不一致;

解决方法:安装程序所需版本的动态库,或重新编译程序使其适配系统中的库版本;

相关推荐
彧azz4 小时前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
-梅5 小时前
linux(8) 软硬链接
linux·运维·服务器
AIgorithmGEEK5 小时前
[Linux]线程三部曲(上):一个执行流的诞生——从操作系统一路拆到 pthread_create
linux·线程·pid
琥珀色糖6 小时前
SimlpeHttp
linux·服务器
qeen876 小时前
【Linux】操作系统之进程介绍(二)
linux·笔记·学习·进程
Zenova EdgeOS6 小时前
Linux ss 工业边缘网络分析实战
linux·python·边缘计算·工业网关
第十人i6 小时前
Linux 日志管理系统:journald 配置与优化
linux·服务器
wuminyu6 小时前
HotSpot的轻量锁与膨胀后的ObjectMonitor状态重建原理
java·linux·c语言·jvm·c++
CCCCCCCCharlie7 小时前
Linux进程控制四大核心操作
linux·开发语言