静态库vs动态库

🔍 什么是静态库和动态库?

静态库(Static Library)

  • 链接时将代码嵌入到最终可执行文件中
  • 文件扩展名:.lib (Windows) 或 .a (Linux/Mac)
  • 可执行文件独立,不依赖外部库文件

动态库(Dynamic Library)

  • 运行时才加载库代码
  • 文件扩展名:.dll (Windows) 或 .so (Linux) / .dylib (Mac)
  • 可执行文件依赖外部库文件

📦 静态库的生成与使用

1. 编写库源码

math_utils.h

复制代码
  #ifndef MATH_UTILS_H
  #define MATH_UTILS_H

  int add(int a, int b);
  int multiply(int a, int b);

  #endif

math_utils.cpp

复制代码
  #include "math_utils.h"

  int add(int a, int b) {
      return a + b;
  }

  int multiply(int a, int b) {
      return a * b;
  }

2. 编译成目标文件

复制代码
  # Linux/Mac
  g++ -c math_utils.cpp -o math_utils.o

  # Windows (MinGW)
  g++ -c math_utils.cpp -o math_utils.o

3. 创建静态库

cpp 复制代码
# Linux/Mac
ar rcs libmath_utils.a math_utils.o

# Windows
ar rcs libmath_utils.a math_utils.o
# 或者使用 MSVC 的 lib 工具
lib /OUT:math_utils.lib math_utils.obj

4. 使用静态库

  • main.cpp
cpp 复制代码
#include <iostream>
#include "math_utils.h"

int main() {
    std::cout << "5 + 3 = " << add(5, 3) << std::endl;
    std::cout << "5 * 3 = " << multiply(5, 3) << std::endl;
    return 0;
}

编译链接:
*

cpp 复制代码
# Linux/Mac
g++ main.cpp -L. -lmath_utils -o main_static

# Windows
g++ main.cpp -L. -lmath_utils -o main_static.exe

📦 动态库的生成与使用

1. 编译成共享对象

cpp 复制代码
# Linux
g++ -fPIC -c math_utils.cpp -o math_utils.o
g++ -shared -o libmath_utils.so math_utils.o

# Mac
g++ -dynamiclib -o libmath_utils.dylib math_utils.o

# Windows (创建 DLL)
g++ -shared -fPIC math_utils.cpp -o math_utils.dll

2. 使用动态库

编译时链接
*

cpp 复制代码
# Linux/Mac
g++ main.cpp -L. -lmath_utils -o main_dynamic

# Windows
g++ main.cpp -L. -lmath_utils -o main_dynamic.exe

运行时注意事项

  • Linux/Mac:确保库路径在 LD_LIBRARY_PATH 环境变量中
  • Windows:确保 DLL 文件在可执行文件同目录或系统 PATH 中

🛠️ 生成库的常用工具

Linux/Mac

cpp 复制代码
# 编译器
gcc/g++          # GNU 编译器套件
clang/clang++    # LLVM 编译器

# 库管理工具
ar               # 创建静态库
ld               # 链接器
objdump          # 查看库信息
nm               # 列出符号表
strip            # 移除符号信息

Windows

cpp 复制代码
# Microsoft Visual Studio
cl.exe           # C/C++ 编译器
link.exe         # 链接器
lib.exe          # 静态库工具
dumpbin.exe      # 查看库信息

# MinGW/MSYS2
gcc/g++          # GNU 工具链
ar               # 库管理

🧩 Makefile 示例

Makefile
*

cpp 复制代码
# 编译器设置
CC = g++
CFLAGS = -Wall -O2

# 目标文件
OBJECTS = math_utils.o
STATIC_LIB = libmath_utils.a
SHARED_LIB = libmath_utils.so
EXECUTABLE_STATIC = main_static
EXECUTABLE_DYNAMIC = main_dynamic

# 默认目标
all: static shared

# 编译目标文件
%.o: %.cpp
	$(CC) $(CFLAGS) -c $< -o $@

# 创建静态库
static: $(OBJECTS)
	ar rcs $(STATIC_LIB) $(OBJECTS)
	$(CC) main.cpp -L. -lmath_utils -o $(EXECUTABLE_STATIC)

# 创建动态库
shared: $(OBJECTS)
	$(CC) -fPIC -c math_utils.cpp -o math_utils.o
	$(CC) -shared -o $(SHARED_LIB) math_utils.o
	$(CC) main.cpp -L. -lmath_utils -o $(EXECUTABLE_DYNAMIC)

# 清理
clean:
	rm -f *.o $(STATIC_LIB) $(SHARED_LIB) $(EXECUTABLE_STATIC) $(EXECUTABLE_DYNAMIC)

.PHONY: all clean static shared

🧩 CMake 示例

CMakeLists.txt
*

cpp 复制代码
cmake_minimum_required(VERSION 3.10)
project(MathLibrary)

set(CMAKE_CXX_STANDARD 17)

# 源文件
set(SOURCES math_utils.cpp)

# 静态库
add_library(math_utils_static STATIC ${SOURCES})
set_target_properties(math_utils_static PROPERTIES OUTPUT_NAME "math_utils")

# 动态库
add_library(math_utils_shared SHARED ${SOURCES})
set_target_properties(math_utils_shared PROPERTIES OUTPUT_NAME "math_utils")
set_target_properties(math_utils_shared PROPERTIES PREFIX "")

# 可执行文件(静态链接)
add_executable(main_static main.cpp)
target_link_libraries(main_static math_utils_static)

# 可执行文件(动态链接)
add_executable(main_dynamic main.cpp)
target_link_libraries(main_dynamic math_utils_shared)

构建命令
*

cpp 复制代码
mkdir build && cd build
cmake ..
make

⚡ 静态库 vs 动态库对比

特性 静态库 (.a/.lib) 动态库 (.so/.dll)
文件大小 可执行文件大 可执行文件小
依赖性 独立运行 依赖库文件
内存使用 每进程独立 多进程共享
更新 需重新编译 只需替换库文件
启动速度 较快 略慢(加载库)
部署 简单(单文件) 需分发库文件

📋 实际操作步骤总结

创建库的完整流程:

  • 编写头文件(.h/.hpp)
  • 编写实现文件(.cpp/.cc)
  • 编译为目标文件(.o/.obj)
  • 打包成库文件
    • 静态库:使用 arlib
    • 动态库:使用 -shared 选项
  • 在其他项目中链接使用
相关推荐
zhangyueping83852 小时前
大模型学习笔记-AI通识
人工智能·笔记·学习
小辉同志2 小时前
45. 跳跃游戏 II
c++·leetcode·游戏·贪心算法
海参崴-2 小时前
C++ 进阶篇 STL 模拟实现二叉搜索树
开发语言·c++
cpp_25012 小时前
P2871 [USACO07DEC] Charm Bracelet S
数据结构·c++·算法·动态规划·题解·洛谷·背包dp
郝学胜-神的一滴2 小时前
深入epoll反应堆模型:从libevent源码看高性能IO设计精髓
linux·服务器·开发语言·c++·网络协议·unix·信息与通信
_F_y2 小时前
C++11 异步操作实现线程池
java·jvm·c++
!停2 小时前
C++入门STL容器Vector使用基础,深挖 Vector替代 C 语言繁琐容器的利器
开发语言·c++
渡己之道2 小时前
笔记-lvgl移植到stm32f407
c语言·笔记·stm32
FakeOccupational2 小时前
【电路笔记 电源模块】“桥接”布局法+电源隔离+GND隔离+统一地平面防干扰
笔记·平面