当前位置: 首页 > news >正文

静态库和动态库

好嘞,直接上干货指令 ✅


✅ 情况 1:你修改了 .cpp.h,使用 静态库(.a

你需要运行的命令:

g++ -c math.cpp -o math.o           # 重新生成目标文件
ar rcs libmath.a math.o             # 重新打包静态库
g++ main.cpp -I. -L. -lmath -o app  # 重新编译并链接主程序
./app                               # 重新运行程序

✅ 情况 2:你修改了 .cpp.h,使用 动态库(.so

如果只改了实现(.cpp),接口没变:

g++ -fPIC -shared math.cpp -o libmath.so  # 重新生成动态库
./app                                     # 直接重新运行主程序即可

✅ 不需要重新编译主程序(前提是接口没变)


如果接口变了(改了 .h 中的函数声明):

g++ -fPIC -shared math.cpp -o libmath.so  # 重新生成动态库
g++ main.cpp -I. -L. -lmath -o app        # 重新编译主程序
./app

你就按这个表走,准没错:

改了啥用静态库要重新编译主程序用动态库要重新编译主程序
.cpp✅ 是❌ 否(接口不变)
.h✅ 是✅ 是(接口变了)

好的,这次我给你详细讲清楚如何手动创建动态库 .so 和静态库 .a,它们之间的本质区别、各自的优点与使用场景,让你彻底搞懂,不止能用、还能讲清楚!


🧱 一、如何创建静态库 .a

静态库就是把 .o 目标文件打包成 .a 文件,然后在编译时一次性“嵌入”进可执行文件。


✅ 示例代码结构:

.
├── main.cpp
├── math.cpp
├── math.h

✅ 文件内容:

math.h
#ifndef MATH_H
#define MATH_H
int add(int a, int b);
#endif
math.cpp
#include "math.h"
int add(int a, int b) {
    return a + b;
}
main.cpp
#include <iostream>
#include "math.h"

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

✅ 创建静态库的指令:

g++ -c math.cpp -o math.o           # 1. 编译为目标文件
ar rcs libmath.a math.o             # 2. 打包为静态库(.a 文件)
g++ main.cpp -I. -L. -lmath -o app  # 3. 编译主程序并链接静态库
./app                               # 4. 运行

🧊 二、如何创建动态库 .so

动态库在程序运行时加载,并不是打包进可执行文件中。多个程序可以共享一个 .so 文件。


✅ 修改 math.cpp 加上 fPIC 编译选项:

g++ -fPIC -c math.cpp -o math.o           # 1. 编译为位置无关代码
g++ -shared -o libmath.so math.o          # 2. 打包为动态库(.so)
g++ main.cpp -I. -L. -lmath -o app        # 3. 编译主程序并链接动态库
export LD_LIBRARY_PATH=.                 # 4. 让系统能找到 .so 文件
./app                                     # 5. 运行

⚔️ 三、静态库 vs 动态库 的区别和优缺点

项目静态库 .a动态库 .so
链接方式编译时链接,直接打包进可执行文件运行时动态加载
文件大小可执行文件体积大可执行文件体积小,依赖 .so 文件
共享性每个程序各自包含一份多个程序共享一份 .so
更新方式更新 .a 后必须重新编译所有用到它的程序只更新 .so 文件,程序可直接使用新版本
性能加载速度略快(不需要运行时查找符号)初始加载稍慢(动态查找函数符号)
部署方便一般更方便,因为不需要额外文件要确保 .so 文件存在并在 LD_LIBRARY_PATH
安全性更稳定、不易被篡改有安全风险(比如恶意篡改 .so

🧠 总结一句话:

✅ 静态库适合体积小、依赖少、无需频繁更新的程序;

✅ 动态库适合大型项目、多个程序共享、经常更新库版本的情况。


☑️ 面试加分点:

  • 你能解释 .a vs .so 的运行原理

  • 你知道 .a 被嵌入 .exe.so 是延迟加载(lazy loading)

  • 你知道如何用 nmldd 检查库的符号和依赖


http://www.dtcms.com/a/109060.html

相关文章:

  • 数据结构复习(单调栈,单调队列,KMP,manacher,tire,字符串哈希)
  • HTML 音频(Audio)学习笔记
  • 时间数据的可视化
  • 什么是msvcp140.dll?msvcp140.dll丢失的解决方法又有哪些?
  • 运算放大器(四)滤波电路(滤波器)
  • Apollo配置中心登陆页面表单密码加密提交
  • 2025年通信安全员 B 证考试真题分享
  • Windows 系统 Git 2.15.0 (64位) 下载与安装教程
  • 使用 PyTorch 的 `GradualWarmupScheduler` 实现学习率预热
  • Java全栈面试宝典:线程协作与Spring Bean管理深度解析
  • echarts 各类统计图 高分辨下文字模糊
  • SpringBoot全局exception处理最佳实践
  • MySQL深入
  • P10744 [SEERC 2020] Modulo Permutations 题解
  • 基于Contiue来阅读open-r1中的GRPO训练代码
  • 【Pandas】pandas DataFrame select_dtypes
  • SpringBoot3 整合 Elasticsearch
  • 思维链编程模式下可视化医疗编程具体模块和流程架构分析(全架构与代码版)
  • HMI 设计:提升工业设备操作的便捷性与安全性
  • 网络编程—Socket套接字(UDP)
  • 通过发音学英语单词:从音到形的学习方法
  • 用ChatGPT-5自然语言描述生成完整ERP模块
  • 工作记录 2017-03-24
  • ollama导入huggingface下载的大模型并量化
  • 11_常用函数
  • Golang的文件同步与备份
  • HLS入门之点灯大师
  • IPIP.NET-IP地理位置数据
  • 1. 购物车
  • Sentinel[超详细讲解]-7 -之 -熔断降级[异常比例阈值]