惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Schneier on Security
N
News and Events Feed by Topic
量子位
S
Secure Thoughts
V2EX - 技术
V2EX - 技术
Hugging Face - Blog
Hugging Face - Blog
S
Security Affairs
J
Java Code Geeks
Schneier on Security
Schneier on Security
Google Online Security Blog
Google Online Security Blog
TaoSecurity Blog
TaoSecurity Blog
小众软件
小众软件
S
SegmentFault 最新的问题
www.infosecurity-magazine.com
www.infosecurity-magazine.com
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Privacy International News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
美团技术团队
博客园 - 聂微东
T
Tor Project blog
博客园 - Franky
C
CERT Recently Published Vulnerability Notes
Cyberwarzone
Cyberwarzone
罗磊的独立博客
博客园_首页
The Cloudflare Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
Forbes - Security
Forbes - Security
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
腾讯CDC
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
博客园 - 【当耐特】
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
博客园 - 司徒正美
AWS News Blog
AWS News Blog
WordPress大学
WordPress大学
Jina AI
Jina AI
G
GRAHAM CLULEY
V
V2EX
L
LINUX DO - 最新话题
H
Heimdal Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
IT之家
IT之家

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
同样是库文件,嵌入式静态库和动态库差异到底在哪?
Sharemaker · 2026-06-17 · via 博客园_首页

目录

0、引言

1、内存与磁盘资源占用

1.1、内存与磁盘资源占用

1.2、多进程共享机制

1.3、链接及引用地址

2、程序编译与更新灵活性

2.1、编译流程对比

2.2、更新机制对比

2.3、OTA应用场景

3、模块化与按需加载机制

3.1、加载机制对比

3.2、内存峰值

3.3、系统启动速度

3.4、对比总结

4、部署与维护便捷性

5、总结:嵌入式场景如何选型


0、引言

        在嵌入式开发中我们会将相关代码封装成库,核心目的是:复用、解耦、保密、简化维护、加快编译、稳定可靠。库本质是把通用、稳定、独立的代码编译成二进制/静态文件,给多个项目直接调用,不用重复写源码,如相关驱动外设、通信协议栈、算法模块、安全/保密代码及中间件组件等,在跨平台或跨产品业务中将代码封装成库做的好处包括:

  • 代码复用:一次编写,N 个项目使用
  • 编译更快:库不参与每次编译,大型项目提速明显
  • 降低耦合:底层和上层分离,架构更清晰
  • 保护源码:核心算法 / 安全代码不泄露
  • 稳定可靠:成熟代码封装后不易被破坏
  • 团队协作:分工明确,底层开发 vs 业务开发

        在代码封装成库时,往往选择将其封装为静态链接库(.a/.lib)或者动态链接库(.so/.dll),为了详细对比分析嵌入式开发中动态库与静态库的差异,接下来将从以下四个核心维度深入展开讨论,将以清晰的对比结构输出结论,重点结合嵌入式资源受限特性,阐述两者在实际开发与系统架构中的性能及维护优势​:



1、内存与磁盘资源占用

1.1、内存与磁盘资源占用

        静态库:编译时会将库的所有代码完整拷贝到每个可执行文件中。

        动态库:只在可执行文件中记录引用地址,实际代码只存一份在系统中。

对比项 静态库 动态库
链接方式 编译时将代码完整复制到可执行文件中 运行时按需才加载到内存
可执行文件大小 包含完整库代码,体积大 仅包含符号引用,体积小
磁盘占用 每个应用独立加载库代码 多个应用共享同一份库文件
内存占用 每个进程独立加载完整代码,N 个进程 = N 份代码副本(线性增长) 多进程共享同一份内存代码,N 个进程 ≈ 1 份物理代码 + N 个映射表
运行时内存 启动 10 个相同程序 → 代码段占用 10 倍内存 启动 10 个相同程序 → 代码段仅占 1 倍内存

        这里简单举一个例子展示二进制资源的区别,假设有 3 个音频处理任务,都使用同一个音频算法库,IRAM对固件镜像和运行时内存占用都有影响:

静态库方案 动态库方案

Task1: [代码+Lib] ≈ 50KB IRAM + 10KB DRAM 

Task2: [代码+Lib] ≈ 50KB IRAM + 10KB DRAM 

Task3: [代码+Lib] ≈ 50KB IRAM + 10KB DRAM  

Task1: [代码] + [共享Lib] ≈ 20KB IRAM + 10KB DRAM

Task2: [代码] + [共享Lib] ≈ 20KB IRAM + 10KB DRAM

Task3: [代码] + [共享Lib] ≈ 20KB IRAM + 10KB DRAM 

 总计:150KB IRAM + 30KB DRAM

实际:60KB IRAM + 30KB DRAM(Lib代码共享)

IRAM 节省:约 60% 

1.2、多进程共享机制

静态库模式:每个进程会独立加载一份
进程 A → [app_a + lib_code] → 内存:lib_code × 1 份(进程内)
进程 B → [app_b + lib_code] → 内存:lib_code × 1 份(进程内)
进程 C → [app_c + lib_code] → 内存:lib_code × 1 份(进程内)
总内存 = 3 份 lib_code,占用 3 × Size(lib)
动态库模式:多个进程/应用使用同一个动态库时,操作系统只需将库代码加载到内存一次,所有进程共享这一份代码:
进程 A → [app_a] → 引用共享库 → 内存:PLT/GOT 表 + lib_code × 1 份(全局共享)
进程 B → [app_b] → 引用共享库 → 内存:PLT/GOT 表 + [共享同一份lib_code]
进程 C → [app_c] → 引用共享库 → 内存:PLT/GOT 表 + [共享同一份lib_code]
总内存 ≈ 1 份 lib_code + 3 × 页表开销,节省约 66% 内存占用,(PLT/GOT 表:用于动态链接的跳转表)

1.3、链接及引用地址

        静态库链接方式:可执行文件中直接包含库的机器码链接器会把静态库里被调用到的目标代码段、数据段完整拷贝,嵌入最终可执行文件内部。 程序运行时不再依赖外部库文件,函数调用写死真实内存地址,在代码中静态库调用情况如下:

main(): 
        CALL 0x12345678  ← 直接调用库函数lib_porocess的实际地址 

lib_porocess():库代码直接嵌入

// 实际处理逻辑

  • 0x12345678:库函数编译后固定的物理偏移地址
  • 链接完成后地址永久固化,运行时无需重定位、无需加载外部文件

        动态库链接方式:使用引用地址即可执行文件中只记录符号引用,而不是实际的代码或数据地址,动态库调用不会写死真实地址,是通过PLT/GOT间接跳转,运行时才查找库函数地址,在代码中动态库调用情况如下:             

           PLT:过程链接表,存放跳转指令
           GOT:全局偏移量表,存放实际地址                                                         

main():

        CALL PLT[0]  ← 调用 PLT 表中的跳转指令

PLT[0]: 

        jmp *GOT[1]  ← 跳转到 GOT 表中的地址  

GOT 表(运行前):

        GOT[1] = 0x00000000  ← 引用地址(待填充)

GOT 表(运行后):

        GOT[1] = 0x12345678  ← 实际地址(库lib_porocess加载后) 

        静态库被调用的实际地址和动态库被调用的引用地址对比如下:

对比项 实际地址 引用地址
存储位置 运行时确定 可执行文件中
库函数的真实内存地址 初始为0或占位符
确定时机 程序启动时 编译/链接时
作用 实际执行时的跳转目标 标记需要解析的符号

        虽然引用地址可以减少可执行文件的体积,但是动态库会引入一些额外开销:

开销类型 说明
PLT/GOT 表  用于动态链接的跳转表,占用少量DRAM
运行时链接  启动时解析符号的时间开销
库句柄 每个加载的库需要维护句柄信息

2、程序编译与更新灵活性

2.1、编译流程对比

静态库编译流程:

源码修改 → 重新编译库 → 重新编译所有使用该库的应用 → 重新链接 → 发布
    ↑                                                                                                            ↑
     └──────────── 牵一发而动全身 ───────────────────┘

动态库编译流程:

库源码修改 → 单独编译库 → 发布新库文件 → 无需重新编译/链接应用
                                                                                         ↑
                                                                          主程序应用完全不受影响

2.2、更新机制对比

场景 静态库更新 动态库更新
ABI兼容性 需维护 ABI 稳定,否则调用方需重新编译 无 ABI 约束(直接嵌入二进制)
修复 Bug 必须重新编译整个主程序并重新分发 只需替换 .so/.dll 文件,主程序零改动
功能增强 全量重新编译、测试、部署,影响所有依赖方 独立发布新版动态库,即插即用,模块独立演进
修复/HOTFIX 用户需下载完整安装包 推送一个小补丁文件即可
版本管理难度 高(每次变更都产生新的二进制) 低(语义化版本控制:major.minor.patch)
回滚成本 需重新打包旧版本 替换回旧版 .so 即可
多 SKU 维护 每个 SKU 独立构建流水线,重复工作多 基础库只维护一份,差异模块独立构建发布

2.3、OTA应用场景

        假设需要修复一款音频产品中的libaudio库中的一个音频bug:

静态库方案 动态库方案

  1. 修改 audio.c 源码
  2. 重新编译 libaudio.a
  3. 重新编译 app1, app2, app3, ..., app10
  4. 重新链接所有应用

  5.全量回归测试 (因为二进制全变了)
  6.打包 OTA 升级包,发布 10 个更新的可执行文件

  7.用户端下载完整包并刷机

  1. 修改 audio.c 源码
  2. 重新编译 libaudio.so → libaudio_new.so

  3.针对性测试 库修改功能即可
  4. OTA 差分包,发布 1 个更新的库文件
  5. 所有应用重启后自动使用新版本

  时间成本高,用户带宽成本高   时间成本低,用户带宽成本低

3、模块化与按需加载机制

3.1、加载机制对比

  静态库加载模型 动态库加载模型
编译链接阶段

ld -o app.elf   

app.o 

libaudio.a   → 代码直接拷贝到 app.elf

libcodec.a  → 代码直接拷贝到 app.elf 

libnet.a       → 代码直接拷贝到 app.elf

app.elf 只包含符号引用和 PLT/GOT 表

libaudio.so 独立编译,符号未解析

程序启动阶段

加载 app.elf 到内存

[主程序 + audio + codec + net] 全部代码已存在

无论是否需要,全部占用内存

加载 app.elf 到内存(快速)

libaudio.so 不加载

libcodec.so 不加载 

libnet.so 不加载  

运行时首次调用: 调用 audio_process() 

PLT 触发动态链接器

加载 libaudio.so

解析符号

执行函数 

特点

启动时即完整可用

无论用不用,所有模块都加载 

无法在运行时卸载不需要的模块

启动快速 

按需加载

可卸载不需要的模块 

内存峰值低

3.2、内存峰值

        以支持多种音频场景模式的TWS耳机典型使用场景为例:

静态库方案 动态库方案

全部常驻:

[主程序代码]        200KB  

[音频通话模块]    150KB  ← 即使不用也占用 

[音乐播放模块]    150KB  ← 即使不用也占用

[语音识别模块]    150KB  ← 即使不用也占用 

[音效处理模块]    100KB  ← 即使不用也占用 

[通信传输模块]    100KB  ← 即使不用也占用 

场景:语音通话模式,按需加载:

[主程序代码]        200KB  

[音频通话模块]    150KB  ← 通话需要 

[音乐播放模块]     卸载 ↓  ← 释放 150KB 

[语音识别模块]     卸载 ↓  ← 释放 150KB 

[音效处理模块]    100KB  ← 通话需要

[通信传输模块]    100KB  ← 通话需要   

总占用:850KB

内存峰值:高 

总占用:550KB ← 节省 35%!

内存峰值:低 

3.3、系统启动速度

        静态链接模式下,所有功能代码在系统启动时全部就位,动态库模式下采用 Lazy Loading,系统启动时只初始化核心模块。

        启动时序对比:
        静态库: [全部代码 XIP 映射] → [全部模块初始化] → 就绪     (T=500ms)
        动态库: [核心框架 XIP 映射] → [核心模块初始化] → 就绪     (T=150ms)
                                                                    ↓ 用户切 ANC 时
                                                   [dl_open libanc.so] → 加载完成 (T=+20ms)

        例如对于 TWS 耳机“开盖即听”的体验要求,启动时间从 500ms 缩短到 150ms 是质变。

3.4、对比总结

  静态库 动态库
模块独立性 编译时绑定,所有符号暴露在同一个链接命名空间,容易冲突 运行时绑定,各 .so 独立编译,符号可限制可见性,避免命名冲突
加载时机 程序启动时一次性全量加载 可选择启动时加载或运行时按需加载 (dlopen)
延迟加载支持 不支持 支持 
内存效率 低(全量常驻) 高(按需分配)
启动速度 慢(全量) 快(按需)
插件扩展 困难(需重新编译) 容易(dlopen/dlclose)
条件编译 大量 #ifdef 导致代码可读性差,测试覆盖不全 通过运行时配置决定加载哪些模块,减少 #ifdef 爆炸

4、部署与维护便捷性

        从以下各个维度对比可以大致了解到静态库和动态库各自的部署和维护层面的优势:

维度 静态库 动态库 分析
部署文件数 1 (单文件部署) N+1 (应用+库,需确保依赖链完整), 静态库简单
依赖部署 需要部署库文件 动态库复杂
路径配置 需配置 LD_LIBRARY_PATH 动态库需配置
升级粒度 全量 增量 动态库优势
回滚风险 全量回滚 可单独回滚库 动态库优势
环境一致性 依赖编译环境 依赖运行时环境 视场景而定
兼容性管理 无运行时依赖冲突,部署简单,但仍存在工具链导致的ABI不兼容,全局符号被不同的.a覆盖 需处理 DLL Hell / 版本冲突问题,ABI要求严格,接口不可随意变动 视场景而定
CI/CD 效率 单固件二进制版本管理,流水线串行化 各模块独立版本号,独立流水线 动态库优势
安全性(逆向) 较难分析 库文件可被独立分析 静态库优势
跨语言调用便利性 需重新编译 可直接供不同语言调用 动态库优势
产品合规认证 每次固件变更需全套重新认证 基础库不变时,只认证变更模块,节省认证成本 动态库优势
功能安全认证 执行路径完全固定,堆栈/内存布局可预测,符号表完整静态 延迟绑定导致执行路径在运行时才确定,符号解析失败、版本不匹配等错误在运行时才暴露 静态库优势

5、总结:嵌入式场景如何选型

         可以根据不同的嵌入式设备类型灵活选择不同的库部署方案:

设备类型 Flash/RAM资源 OTA频率 推荐方案 核心理由
TWS耳机/可穿戴 极紧张(MB级Flash) 高(持续迭代功能)
动态静态混合:核心协议栈静态链接,功能算法模块动态加载
模块级差分 OTA 包可缩小到 KB 级(vs 全量 MB 级),BLE 传输时间大大降低;按需加载可缩短关键启动路径 30-50%
智能音箱/IoT网关 中等 中高 首选动态库 资源充裕可承担加载器开销;多进程/多服务天然受益代码共享;插件式技能/算法更新是刚需
车规MCU 紧张但安全优先 极低(年/次) 静态库(确定性 + 安全认证便利性) 确定性执行、无动态加载器故障面;功能安全认证(对动态加载的验证成本极高)
工业控制 紧张 极低 静态库 硬实时约束下 PIC 间接跳转和加载延迟不可接受;单次部署后很少变更
传感器节点/电池供电 极紧张 静态库(禁止动态加载器开销) 加载器的开销占比过大;无 OTA 需求则动态库无优势
Linux嵌入式 充裕 动态库全面采用 MMU 提供天然进程隔离;动态库生态成熟;插件式功能扩展是产品核心架构

        例如本博主参与开发的音频产品(智能耳机/音箱)恰好是动态库模式的最佳受益者:

  1. 功能模块明确:ANC、EQ、语音唤醒、本地音乐、空间音频——天然模块化边界;
  2. OTA 要求高:消费音频产品功能迭代频繁,差分 OTA 显著改善用户体验和升级成功率;
  3. 多 SKU 共存:同一 SDK 产出降噪款/基础款/游戏款等不同固件;                                       
  4. 第三方算法集成:ANC 和音效算法通常由外部供应商提供,so动态库是必要前提;            
  5. 多核架构适配:MCU + DSP共享代码段,动态链接直接解决多核代码冗余问题。

        结论:在资源受限的嵌入式环境中,动态库直接对应现代软件架构对资源效率、模块解耦、热更新的三大核心诉求,其对于需要持续演进的中大型项目是一个效率较高的方案。而静态库则在安全敏感、极致性能场景中保持其不可替代性,更适合作为特定约束条件下的补充方案(如极简部署、安全隔离场景),因此在软件架构设计上可以考虑静态+动态混合部署:核心框架用动态库保证灵活性,第三方闭源库或极小工具可用静态库简化部署。

混合架构部署模型

使用静态库:

  • 启动引导程序 (bootloader) 
  • 中断处理代码
  • 实时性要求极高的算法
  • 极简内核/基础库
  • 单体小型工具 / 追求极致简单部署,无需附带依赖库
  • 安全敏感场景(避免外部依赖注入风险)
  • 极端性能优化,函数调用无间接跳转,执行效率略高(消除 PLT/GOT 开销)
  • 交叉编译环境受限(无动态链接器支持)
  • 确保库版本一致性,避免DLL Hell问题

使用动态库: 

  • 频繁迭代更新的模块(如算法库、音频/视频编解码库)  
  • 网络协议栈  
  • 第三方 SDK 
  • 可选功能模块
  • 频繁更新的业务逻辑
  • 大型项目 / 多模块协作
  • 多个程序共享通用组件
  • 插件化 / 可扩展架构
  • OTA/热更新敏感的嵌入式设备
  • 需要跨语言调用的中间件

混合架构优势:

  • 关键代码零链接开销
  • 非关键代码灵活更新
  • 内存效率与灵活性兼顾

↓↓↓更多技术内容和书籍资料获取,入群技术交流敬请关注“明解嵌入式”↓↓↓