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);

(三)动态库版本冲突

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

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

相关推荐
叼烟扛炮1 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
xbzb2 小时前
OpenStack 网络管理(理论):Linux 网络虚拟化是 Neutron 的地基
linux·服务器·网络·openstack·network·neutron
Android系统攻城狮3 小时前
Linux FFmpeg深度解析之avcodec_flush_buffers调用流程与实战(十九)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频进阶
水饺编程4 小时前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
Zevalin爱灰灰5 小时前
Linux入门第二部分(ARM裸机篇) 第二章 Cortex-A7 MPCore架构与ARM汇编基础
linux·汇编·arm开发·嵌入式
倔强的石头1065 小时前
【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语
linux·运维·服务器
GeW5 小时前
从"补短板"到"强优势"Linux与数据库认证成为产业跃迁人才支点
linux·数据库
PellyKoo7 小时前
【Ubuntu】GTX 1080 Ti 显卡占用为0但功率高达60W的排查与解决
linux·运维·ubuntu
Fruiticecake8 小时前
epoll 回显服务器是怎么工作的:从 accept 队列到就绪链表,以及它和 select / poll 的区别
linux
承渊政道8 小时前
Linux网络学习【从NAT与代理服务理解网络转发、探索内网穿透原理、再到认识DNS与ICMP、最后动手部署并测试内网穿透】
linux·网络·学习·内网穿透·dns·nat