十二、C++速通秘籍—静态库,动态库

上一章节:

十一、C++速通秘籍—多线程-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/147055932?spm=1001.2014.3001.5502

本章节代码:

cpp2/library · CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/master/cpp2/library

目录

上一章节:

本章节代码:

一、编程后为什么会引入“库”,什么是库?

二、库分为哪几类? - 静态库,动态库

1、静态库(.a 或.lib)

2、动态库(.so 或.dll)

三、Linux/windows系统下的库

1、Linux 下表现形式

2、Windows 下表现形式

四、Linux/Windows下使用静态库,什么场景下使用静态库?

1、适用场景

2、Linux 下创建和使用静态库

2.1、创建静态库

2.2、使用静态库

3、Windows 下创建和使用静态库

3.1、创建静态库

3.2、使用静态库

五、Linux/Windows下使用动态库,什么场景下使用动态库?

1、适用场景

2、Linux 下创建和使用动态库

2.1、创建动态库

2.1、使用动态库

3、Windows 下创建和使用动态库

3.1、创建动态库

六、静态库,与动态库二者的区别

内存占用

部署难度

运行效率

可维护性

七、总结


一、编程后为什么会引入“库”,什么是库?

        想象一下你是一位超级大厨,每次做饭都要从头开始种粮食、养牲畜、采摘蔬菜,那得花费多少时间和精力呀!在编程的世界里也是如此,如果每次编写程序都要从头开始实现一些常用的功能,比如文件读写、数学计算等,那程序员可就太累啦。于是,“库”就应运而生了。

        库就像是一个装满各种工具的百宝箱,里面存放着已经编写好的代码,这些代码实现了各种各样的功能。当程序员需要使用某个功能时,不需要自己重新编写代码,只需要从这个百宝箱里拿出对应的工具(也就是调用库中的代码)就可以了。比如说,在 C++ 中,我们之前已经接触过std标准库,就提供了很多常用的功能,像字符串处理、容器管理等。你只需要包含相应的头文件,就可以使用这些功能,就像大厨从厨房里拿出现成的调料一样方便。

二、库分为哪几类? - 静态库,动态库

库主要分为两类:静态库和动态库,它们就像是两种不同类型的百宝箱。

1、静态库(.a 或.lib)

        静态库就像是一个可以被复制的百宝箱。当你使用静态库时,编译器会把静态库中的代码完整地复制到你的可执行文件中。这就好比你把百宝箱里的工具都拿出来,放进自己的口袋里,以后无论走到哪里,都可以随时使用这些工具,不需要再依赖原来的百宝箱。

2、动态库(.so 或.dll)

        动态库则像是一个共享的百宝箱,存放在一个公共的地方。当你的程序需要使用动态库中的代码时,程序会在运行时去这个公共的地方查找并加载所需的代码。这就好比你需要某个工具时,不需要把整个百宝箱都拿走,只需要去公共的地方借用一下工具,用完后再还回去。

三、Linux/windows系统下的库

1、Linux 下表现形式

在 Linux 系统中,静态库的文件扩展名通常是 `.a`,例如 `libexample.a`;动态库的文件扩展名通常是 `.so`,例如 `libexample.so`。这些库文件一般存放在 `/usr/lib` 或 `/usr/local/lib` 等目录下。

2、Windows 下表现形式

在 Windows 系统中,静态库的文件扩展名是 `.lib`,例如 `example.lib`;动态库的文件扩展名是 `.dll`,例如 `example.dll`。这些库文件通常存放在系统目录(如 `C:\Windows\System32`)或程序的安装目录下

下面是一个简单的对比图:

系统

静态库扩展名

动态库扩展名

Linux

.a

.so

Windows

.lib

.dll

四、Linux/Windows下使用静态库,什么场景下使用静态库?

1、适用场景

当你需要将程序打包成一个独立的可执行文件,并且不希望依赖外部的库文件时,就可以使用静态库。比如你开发了一个小型的游戏,希望用户下载后可以直接运行,不需要额外安装其他库,这时就可以使用静态库。

2、Linux 下创建和使用静态库

2.1、创建静态库

假设我们有一个简单的 C++ 函数 `add`,用于计算两个整数的和,代码如下:

add.cpp

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

首先,将 `add.cpp` 编译成目标文件:(add.o)

g++ -c add.cpp -o add.o

然后,使用 `ar` 工具将目标文件打包成静态库:

ar rcs libadd.a add.o

这样,我们就创建了一个名为 `libadd.a` 的静态库。

2.2、使用静态库

现在,我们来编写一个主程序 `main.cpp` 来使用这个静态库:

main.cpp

#include <iostream>// 声明 add 函数
extern int add(int a, int b);int main() {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;return 0;
}

编译并链接静态库:

g++ main.cpp -L. -ladd -o main

其中,`-L.` 表示在当前目录下查找库文件,`-ladd` 表示链接名为 `libadd.a` 的静态库。最后,运行可执行文件:

./main

3、Windows 下创建和使用静态库

3.1、创建静态库

同样使用上面的 `add.cpp` 代码,打开 VisualCode,创建一个 `add.cpp`文件。

代码:

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

这里编译生成.lib,这里需要修改VsCode,中的tasks.json;

通过这个文件创建了两个编译任务:create_targe_file/create_static_lib

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成静态库"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

(1)、打开命令面板(Ctrl+Shift+P)

(2)、输入 Tasks: Run Task 并选择 create_target_file

(3)、创建静态库,跟步骤2相同选择create_static_lib

3.2、使用静态库

创建一个staticEx.cpp

// 链接静态库
#include <iostream>// 声明 addWin 函数
extern "C" int addWin(int a, int b);int main() {int result = addWin(5, 5);std::cout << "5 + 5 = " << result << std::endl;return 0;
}

配置tasks.json:

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成静态库"label": "create_static_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\ar.exe","args": ["rcs","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.lib","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 生成可执行文件"label": "create_exe_file","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c",   // 编译参数"${file}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-static"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

五、Linux/Windows下使用动态库,什么场景下使用动态库?

1、适用场景

当多个程序需要共享相同的代码,或者库文件需要经常更新时,使用动态库就非常合适。比如操作系统中的一些公共库,多个程序都可以使用这些库中的功能,这样可以节省系统资源。

2、Linux 下创建和使用动态库

2.1、创建动态库

还是使用上面的 `add.cpp` 代码,将其编译成动态库:

g++ -fPIC -c add.cpp -o add.o
g++ -shared -o libadd.so add.o

其中,`-fPIC` 选项用于生成位置无关代码,`-shared` 选项用于创建动态库。

2.1、使用动态库

编写主程序 `main.cpp`:

// main.cpp
#include <iostream>// 声明 add 函数
extern int add(int a, int b);int main() {int result = add(9, 8);std::cout << "9 + 8 = " << result << std::endl;return 0;
}

编译并链接动态库:


g++ main.cpp -L. -ladd -o mainso

运行程序前,需要设置动态库的搜索路径:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./main

3、Windows 下创建和使用动态库

3.1、创建动态库

在 VsCode 中创建两个文件`dyAdd.h/dyAdd.cpp`, 在dyAdd.h中添加一个导出函数的声明,dyAdd.cpp中实现函数功能:

dyAdd.h

// 动态库
#ifndef _DYADD_H_
#define _DYADD_H_#ifdef DYADD_DLL_EXPORTS
#define DYADD_API __declspec(dllimport)
#else
#define DYADD_API __declspec(dllexport) // 导出
#endifextern "C" DYADD_API int add(int a, int b);#endif

dyAdd.cpp

#include "dyAdd.h"extern "C" DYADD_API int add(int a, int b)
{return a + b;
}

tasks.json

{"tasks": [{ // 生成目标文件"type": "shell","label": "create_target_file","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-c","${file}","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-DDYADD_EXPORTS" // 添加此行以定义 DYADD_EXPORTS 宏],"options": {"cwd": "${fileDirname}"},"problemMatcher": ["$gcc"],"group": {"kind": "build","isDefault": true}},{ // 生成动态库"label": "create_dynamic_lib","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","-shared","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.o","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.dll"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"},{ // 通过动态库生成可执行文件"label": "create_exe_dyfile","type": "shell","command": "C:\\Qt\\Qt5.12.8\\Tools\\mingw730_64\\bin\\g++.exe","args": ["-fdiagnostics-color=always","-g","${file}","-I${fileDirname}","-L${fileDirname}\\..\\..\\build","-o","${fileDirname}\\..\\..\\build\\${fileBasenameNoExtension}.exe","-ladd"],"group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always"},"problemMatcher": "$gcc"}],"version": "2.0.0"
}

这里第一步,第二步,执行后生成了dyAdd.dll,以及编译的中间文件dyAll.o,编译方法都是通过控制面板按步骤生成:

使用动态库

dynamicEx.cpp

#include <iostream>
#include <windows.h>// 动态加载
typedef int (*AddFunction)(int, int);int main() {HINSTANCE hDLL = LoadLibrary("dyAdd.dll");if (hDLL != NULL) {AddFunction add = (AddFunction)GetProcAddress(hDLL, "add");if (add != NULL) {int result = add(3, 5);std::cout << "3 + 5 = " << result << std::endl;}else {std::cout << "Failed to get add function address." << std::endl;}FreeLibrary(hDLL);}return 0;
}

编译并运行程序

六、静态库,与动态库二者的区别

内存占用

静态库会将代码复制到可执行文件中,导致可执行文件体积较大,占用更多的磁盘空间;而动态库在多个程序间共享,只需要在内存中加载一份,节省了磁盘空间和内存资源。

部署难度

静态库部署简单,可执行文件不依赖外部库文件,用户只需要运行可执行文件即可;动态库部署时需要确保库文件存在于系统的指定路径中,否则程序可能无法正常运行。

运行效率

静态库的代码在编译时就已经链接到可执行文件中,运行时无需额外加载,效率相对较高;动态库在运行时需要加载,会有一定的性能开销。

可维护性

如果库文件需要更新,使用静态库的程序需要重新编译;而使用动态库的程序只需要替换库文件即可,不需要重新编译。

下面是一个对比表格:

比较项

静态库

动态库

内存占用

部署难度

简单

复杂

运行效率

可维护性

七、总结

        掌握静态库和动态库的使用,能让你的 C++ 编程之路更加顺畅,就像大厨拥有了得心应手的工具,做出更加美味的菜肴一样!希望通过这篇博客,你能对静态库和动态库有更深入的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75517.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是继承?js中有哪儿些继承?

1、什么是继承&#xff1f; 继承是面向对象软件技术中的一个概念。 2、js中有哪儿些继承&#xff1f; js中的继承有ES6的类class的继承、原型链继承、构造函数继承、组合继承、寄生组合继承。 2.1 ES6中类的继承 class Parent {constructor() {this.age 18;} }class Chil…

Linux进程通信入门:匿名管道的原理、实现与应用场景

Linux系列 文章目录 Linux系列前言一、进程通信的目的二、进程通信的原理2.1 进程通信是什么2.2 匿名管道通讯的原理 三、进程通讯的使用总结 前言 Linux进程间同通讯&#xff08;IPC&#xff09;是多个进程之间交换数据和协调行为的重要机制&#xff0c;是我们学习Linux操作系…

探秘Transformer系列之(26)--- KV Cache优化 之 PD分离or合并

探秘Transformer系列之&#xff08;26&#xff09;— KV Cache优化 之 PD分离or合并 文章目录 探秘Transformer系列之&#xff08;26&#xff09;--- KV Cache优化 之 PD分离or合并0x00 概述0x01 背景知识1.1 自回归&迭代1.2 KV Cache 0x02 静态批处理2.1 调度策略2.2 问题…

十大PDF解析工具在不同文档类别中的比较研究

PDF解析对于包括文档分类、信息提取和检索在内的多种自然语言处理任务至关重要&#xff0c;尤其是RAG的背景下。尽管存在各种PDF解析工具&#xff0c;但它们在不同文档类型中的有效性仍缺乏充分研究&#xff0c;尤其是超出学术文档范畴。通过使用DocLayNet数据集&#xff0c;比…

HarmonyOS-ArkUI 装饰器V2 @ObservedV2与@Trace装饰器

参考文档: 文档中心https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/arkts-new-observedv2-and-trace-V14#trace%E8%A3%85%E9%A5%B0%E5%AF%B9%E8%B1%A1%E6%95%B0%E7%BB%84由于V2的装饰器比V1的装饰器更加易用,尽管学习的过程中用到的都是V1的装饰器,但…

GPT - GPT(Generative Pre-trained Transformer)模型框架

本节代码主要为实现了一个简化版的 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型。GPT 是一种基于 Transformer 架构的语言生成模型&#xff0c;主要用于生成自然语言文本。 1. 模型结构 初始化部分 class GPT(nn.Module):def __init__(self, vocab…

基于FPGA的六层电梯智能控制系统 矩阵键盘-数码管 上板仿真均验证通过

基于FPGA的六层电梯智能控制系统 前言一、整体方案二、软件设计总结 前言 本设计基于FPGA实现了一个完整的六层电梯智能控制系统&#xff0c;旨在解决传统电梯控制系统在别墅环境中存在的个性化控制不足、响应速度慢等问题。系统采用Verilog HDL语言编程&#xff0c;基于Cyclo…

车载通信系统中基于ISO26262的功能安全与抗辐照协同设计研究

摘要&#xff1a;随着智能网联汽车的快速发展&#xff0c;车载通信系统正面临着功能安全与抗辐照设计的双重挑战。在高可靠性要求的车载应用场景下&#xff0c;如何实现功能安全标准与抗辐照技术的协同优化&#xff0c;构建满足ISO26262安全完整性等级要求的可靠通信架构&#…

Node.js种cluster模块详解

Node.js 中 cluster 模块全部 API 详解 1. 模块属性 const cluster require(cluster);// 1. isMaster // 判断当前进程是否为主进程 console.log(是否为主进程:, cluster.isMaster);// 2. isWorker // 判断当前进程是否为工作进程 console.log(是否为工作进程:, cluster.isW…

融合动态权重与抗刷机制的网文评分系统——基于优书网、IMDB与Reddit的混合算法实践

✨ Yumuing 博客 &#x1f680; 探索技术的每一个角落&#xff0c;解码世界的每一种可能&#xff01; &#x1f48c; 如果你对 AI 充满好奇&#xff0c;欢迎关注博主&#xff0c;订阅专栏&#xff0c;让我们一起开启这段奇妙的旅程&#xff01; 以权威用户为核心&#xff0c;时…

使用Golang打包jar应用

文章目录 背景Go 的 go:embed 功能介绍与打包 JAR 文件示例1. go:embed 基础介绍基本特性基本语法 2. 嵌入 JAR 文件示例项目结构代码实现 3. 高级用法&#xff1a;嵌入多个文件或目录4. 使用注意事项5. 实际应用场景6. 完整示例&#xff1a;运行嵌入的JAR 背景 想把自己的一个…

前端大屏可视化项目 局部全屏(指定盒子全屏)

需求是这样的&#xff0c;我用的项目是vue admin 项目 现在需要在做大屏项目 不希望显示除了大屏的其他东西 于是想了这个办法 至于大屏适配问题 请看我文章 底部的代码直接复制就可以运行 vue2 px转rem 大屏适配方案 postcss-pxtorem-CSDN博客 <template><div …

《2025蓝桥杯C++B组:D:产值调整》

**作者的个人gitee**​​ 作者的算法讲解主页▶️ 每日一言&#xff1a;“泪眼问花花不语&#xff0c;乱红飞过秋千去&#x1f338;&#x1f338;” 题目 二.解题策略 本题比较简单&#xff0c;我的思路是写三个函数分别计算黄金白银铜一次新产值&#xff0c;通过k次循环即可获…

[VTK] 四元素实现旋转平移

VTK 实现旋转&#xff0c;有四元数的方案&#xff0c;也有 vtkTransform 的方案&#xff1b;主要示例代码如下&#xff1a; //构造旋转四元数vtkQuaterniond rotation;rotation.SetRotationAngleAndAxis(vtkMath::RadiansFromDegrees(90.0),0.0, 1.0, 0.0);//构造旋转点四元数v…

华为hcie证书的有效期怎么判断?

在ICT行业&#xff0c;华为HCIE证书堪称含金量极高的“敲门砖”&#xff0c;拥有它往往意味着在职场上更上一层楼。然而&#xff0c;很多人在辛苦考取HCIE证书后&#xff0c;却对其有效期相关事宜一知半解。今天&#xff0c;咱们就来好好唠唠华为HCIE证书的有效期怎么判断这个关…

【精品PPT】2025固态电池知识体系及最佳实践PPT合集(36份).zip

精品推荐&#xff0c;2025固态电池知识体系及最佳实践PPT合集&#xff0c;共36份。供大家学习参考。 1、中科院化学所郭玉国研究员&#xff1a;固态金属锂电池及其关键材料.pdf 2、中科院物理所-李泓固态电池.pdf 3、全固态电池技术研究进展.pdf 4、全固态电池生产工艺.pdf 5、…

MySQL 中为产品添加灵活的自定义属性(如 color/size)

方案 1&#xff1a;EAV 模型&#xff08;最灵活但较复杂&#xff09; 适合需要无限扩展自定义属性的场景 -- 产品表 CREATE TABLE products (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100),price DECIMAL(10,2) );-- 属性名表 CREATE TABLE attributes (id INT PRIMA…

CSPM认证对项目论证的范式革新:从合规审查到价值创造的战略跃迁

引言 在数字化转型浪潮中&#xff0c;全球企业每年因项目论证缺陷导致的损失高达1.7万亿美元&#xff08;Gartner 2023&#xff09;。CSPM&#xff08;Certified Strategic Project Manager&#xff09;认证体系通过结构化方法论&#xff0c;将传统的项目可行性评估升级为战略…

CLIP中的Zero-Shot Learning原理

CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;是一种由OpenAI提出的多模态模型&#xff0c;它通过对比学习的方式同时学习图像和文本的表示&#xff0c;并且能在多种任务中进行零样本学习&#xff08;Zero-Shot Learning&#xff09;。CLIP模型的核心创…

spring mvc 中 RestTemplate 全面详解及示例

RestTemplate 全面详解及示例 1. RestTemplate 简介 定义&#xff1a;Spring 提供的同步 HTTP 客户端&#xff0c;支持多种 HTTP 方法&#xff08;GET/POST/PUT/DELETE 等&#xff09;&#xff0c;用于调用 RESTful API。核心特性&#xff1a; 支持请求头、请求体、URI 参数的…