【C++】动态库和静态库详细说明

本文梳理了 静态库、动态库、链接、运行时依赖 的关系,并结合 Windows/C++/CMake 场景说明。


一、 静态库(Static Library)

1. 定义

  • 静态库是一种在 编译链接阶段就被打包到可执行文件中的库。
  • 在 Windows 上通常是 .lib 文件(对应 CMake 的 STATIC),Linux 上是 .a 文件。

2. 特点

  1. 链接时合并
    • 编译器把静态库里的目标文件(.obj/.o)直接打包到可执行文件中。
  2. 运行时不依赖库文件
    • 可执行文件独立运行,不需要 .lib.a 文件。
  3. 多个程序独立打包
    • 每个可执行文件都会有自己的一份库代码,占用更多磁盘/内存。

3. 优缺点

优点缺点
运行时不依赖库文件可执行文件变大
链接简单,部署方便更新库需要重新编译可执行文件
不会出现 DLL Hell不能在多个程序间共享内存代码

4. CMake 示例

add_library(common STATIC ${MODULE_SOURCES})
target_include_directories(common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
  • 编译后生成 common.lib
  • 链接到可执行文件:
target_link_libraries(myapp PRIVATE common)

二、 动态库(Shared Library)

1. 定义

  • 动态库是在 运行时加载的库。
  • Windows 上是 .dll 文件(对应 CMake 的 SHARED),Linux 是 .so 文件。

2. 特点

  • 运行时依赖
    • 可执行文件需要找到 DLL 才能运行。
  • 内存共享
    • 多个程序可以同时加载同一个 DLL,节省内存。
  • 更新方便
    • 更新 DLL 不需要重新编译可执行文件(只要接口不变)。

3. 优缺点

优点缺点
可执行文件小运行时必须找到 DLL
多程序共享代码出现版本冲突(DLL Hell)
支持插件机制链接复杂,需要导入库

4. CMake 示例

add_library(common SHARED ${MODULE_SOURCES})
target_include_directories(common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
  • 生成 common.dllcommon.lib(导入库)
  • 链接可执行文件:
target_link_libraries(myapp PRIVATE common)
  • 运行时
    • Windows 下 common.dll 需要在 PATH 中或和 exe 同目录
    • Linux 下 .so 需要在 LD_LIBRARY_PATH 中或 /usr/lib

三、 链接(Linking)

1. 链接类型

  • 静态链接(Static Linking)
    • 编译器把 .lib / .a 内容直接嵌入可执行文件
    • 运行时不需要库文件
  • 动态链接(Dynamic Linking)
    • 编译时只需要导入库(Windows .dll 或 Linux .so 的接口)
    • 运行时加载实际的 DLL / SO

2. 链接过程

  • 编译(Compile)
    • .cpp.obj(Windows)或 .o(Linux)
  • 链接(Link)
    • 把目标文件 .obj 和库文件 .lib / .a / .dll 组合成最终可执行文件
  • 运行(Run)
    • 静态库已经在 exe 里,不需要库文件
    • 动态库需要系统找到 DLL / SO

四、 CMake 中的控制

CMake 指令功能
add_library(foo STATIC ...)生成静态库 .lib / .a
add_library(foo SHARED ...)生成动态库 .dll / .so + 导入库
target_link_libraries(myapp PRIVATE foo)链接库到可执行文件,PRIVATE 表示只对当前目标可见
CMAKE_ARCHIVE_OUTPUT_DIRECTORY静态库输出路径
CMAKE_LIBRARY_OUTPUT_DIRECTORY动态库输出路径
CMAKE_RUNTIME_OUTPUT_DIRECTORY可执行文件输出路径

五、 Windows 下静态库与动态库的区别

类型文件链接时运行时输出目录
静态库.lib需要不需要CMAKE_ARCHIVE_OUTPUT_DIRECTORY
动态库.dll + .lib(导入库)需要导入库(并不是静态库),用于链接符号需要 DLLCMAKE_LIBRARY_OUTPUT_DIRECTORY(DLL)
可执行文件.exe链接库运行时依赖 DLLCMAKE_RUNTIME_OUTPUT_DIRECTORY

六、 编译-链接-运行流程

在这里插入图片描述

🔹说明:

  1. 静态库
    • .lib 在链接阶段合并到 exe
    • 运行 exe 不需要 .lib 文件
  2. 动态库
    • 链接阶段使用导入库 .lib
    • 运行时必须能找到对应的 .dll
  3. CMake 配置
    • CMAKE_ARCHIVE_OUTPUT_DIRECTORY → 静态库输出
    • CMAKE_LIBRARY_OUTPUT_DIRECTORY → 动态库输出
    • CMAKE_RUNTIME_OUTPUT_DIRECTORY → exe 输出
  4. VS 工程显示
    • 每个模块的源文件和头文件可通过 source_group 管理
    • 可执行文件和库文件目录可以统一管理

如果这篇文章对你有所帮助,渴望获得你的一个点赞!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OpenC++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值