【学习日记】静态库与动态库的区别及使用指南

news2024/11/13 15:07:27

文章目录

  • 静态库与动态库的区别及使用指南
    • 静态库
      • 定义
      • 使用方式
      • 优点
      • 缺点
      • 使用示例
        • 创建静态库
        • 使用静态库
    • 动态库
      • 定义
      • 工作原理
      • 优点
      • 缺点
      • 使用示例
        • 创建动态库
        • 使用动态库
    • 如何区分静态库和动态库
    • 总结
  • 封面

静态库与动态库的区别及使用指南

本文将详细介绍这两种库的定义、工作原理、优缺点及使用示例。

静态库

定义

静态库是一组预编译的对象文件的集合,这些对象文件在编译期间被链接到程序中。静态库通常具有 .a 扩展名(在 Unix 系统上)或 .lib 扩展名(在 Windows 系统上)。

使用方式

  1. 创建静态库

    • 将源代码文件编译成对象文件(.o 文件)。
    • 使用归档工具(如 ar 在 Unix 系统上)将这些对象文件打包成一个静态库(.a 文件)。
  2. 链接静态库

    • 在编译应用程序时,链接器将静态库中的代码与应用程序的代码进行链接,生成一个独立的可执行文件。
    • 这个可执行文件包含了所有必要的代码,可以在没有外部库的环境中运行。

优点

  1. 性能:静态链接在编译时完成,不需要在运行时加载库文件,使得程序启动和运行速度更快。
  2. 独立性:生成的可执行文件包含了所有所需的代码,可以在没有原始库的环境中运行。
  3. 版本控制:库的版本在编译时确定,避免了运行时的兼容性问题。

缺点

  1. 文件大小:静态链接会增加最终可执行文件的大小,因为所有库代码都被包含进去。
  2. 更新困难:如果静态库中的代码有更新,需要重新编译所有使用该库的程序。
  3. 重复内容:多个使用相同静态库的程序会包含库的副本,导致磁盘空间浪费。

使用示例

假设我们有两个源文件,math_functions.cppstring_functions.cpp,它们分别实现了一些数学和字符串操作函数。

// math_functions.cpp
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

// string_functions.cpp
#include <string>

std::string concatenate(const std::string& a, const std::string& b) {
    return a + b;
}
创建静态库
  1. 编译源文件为对象文件:

    g++ -c math_functions.cpp string_functions.cpp
    
  2. 使用 ar 工具创建静态库:

    ar rcs libmylibrary.a math_functions.o string_functions.o
    
使用静态库

假设我们有一个主程序 main.cpp,需要使用静态库中的函数:

// main.cpp
#include <iostream>
#include <string>

extern int add(int a, int b);
extern int subtract(int a, int b);
extern std::string concatenate(const std::string& a, const std::string& b);

int main() {
    std::cout << "Add: " << add(2, 3) << std::endl;
    std::cout << "Subtract: " << subtract(5, 3) << std::endl;
    std::string result = concatenate("Hello, ", "world!");
    std::cout << "Concatenate: " << result << std::endl;
    return 0;
}

编译并链接主程序与静态库:

g++ main.cpp -L. -lmylibrary -o myprogram

运行程序:

./myprogram

动态库

定义

动态库是在程序运行时加载的库。动态库通常具有 .so 扩展名(在 Unix 系统上)或 .dll 扩展名(在 Windows 系统上)。

工作原理

  1. 创建动态库

    • 将源代码文件编译成对象文件,使用 -fPIC 选项生成位置无关代码。
    • 使用编译器生成共享对象文件(.so 文件)。
  2. 链接动态库

    • 在编译期间,只需建立一个符号链接,实际的库代码在程序运行时加载。

优点

  1. 文件大小:由于库代码不在可执行文件中,可执行文件会比较小。
  2. 更新方便:动态库可以独立于应用程序进行更新。只需更新库文件,不需要重新编译依赖该库的程序。

缺点

  1. 运行时依赖:生成的可执行文件在运行时需要找到并加载动态库文件。如果库文件缺失,程序将无法运行。
  2. 性能:由于库在程序运行时加载,可能会影响程序启动速度。

使用示例

假设我们有一个动态库 libmylib.so,其包含了一些数学函数。

创建动态库
  1. 编译源文件为对象文件:

    g++ -fPIC -c math_functions.cpp
    
  2. 创建动态库:

    g++ -shared -o libmylib.so math_functions.o
    
使用动态库

假设我们有一个主程序 main.cpp,需要使用动态库中的函数:

// main.cpp
#include <iostream>
#include <string>

extern int add(int a, int b);
extern int subtract(int a, int b);
extern std::string concatenate(const std::string& a, const std::string& b);

int main() {
    std::cout << "Add: " << add(2, 3) << std::endl;
    std::cout << "Subtract: " << subtract(5, 3) << std::endl;
    std::string result = concatenate("Hello, ", "world!");
    std::cout << "Concatenate: " << result << std::endl;
    return 0;
}

编译并链接主程序与动态库:

g++ main.cpp -L. -lmylib -o myprogram

运行时设置 LD_LIBRARY_PATH 环境变量来指定动态库的位置:

export LD_LIBRARY_PATH=.
./myprogram

如何区分静态库和动态库

  1. 文件扩展名:静态库通常是 .a.lib,动态库通常是 .so.dll
  2. 编译和链接命令
    • 静态库:在编译命令中使用 -l 选项链接静态库。
    • 动态库:在编译命令中使用 -l 选项链接动态库,并在运行时需要找到库文件。
  3. 可执行文件依赖
    • 静态库:生成的可执行文件不依赖外部库文件。
    • 动态库:生成的可执行文件在运行时需要找到并加载库文件。

总结

  • 静态库:在编译期间被链接到程序中,生成的可执行文件包含库代码。
  • 动态库:在程序运行时加载,生成的可执行文件依赖外部库文件。

封面

使用 DALL-E-3 生成。
在这里插入图片描述

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

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

相关文章

【机器学习】为什么使用Scikit-Learn来进行逻辑回归以及如何使用Scikit-Learn进行逻辑回归

引言 在Scikit-Learn中&#xff0c;逻辑回归是通过LogisticRegression类实现的。该类提供了多种方法来训练模型、进行预测以及评估模型性能。用户可以自定义许多参数&#xff0c;包括正则化类型&#xff08;L1、L2或弹性网&#xff09;、求解器类型&#xff08;用于优化问题&am…

Cesium初探

Cesium 是一个开源 JavaScript 库&#xff0c;用于创建 3D 地理空间应用程序。它允许开发者在 Web 浏览器中构建高性能、交互式的 3D 地图和地球可视化应用&#xff0c;而无需安装任何插件。Cesium 支持多种数据格式&#xff0c;包括 3D Tiles&#xff08;一种高效的 3D 场景流…

变量作用域、作用域链、return

全局变量 全局变量因为在全局操作会每次留存上次操作的结果 局部变量因为执行完成就会被销毁并不会保留本次操作的结果 可以通过传参和返回&#xff0c;将结果不断地专递处理 局部变量 参数也是局部变量 函数内的预解析预赋值 函数内的局部变量 如果同名全局变量遇到局部变量…

Java的jstat命令输出GC信息时携带时间信息(Windows系统中)

之前写了一篇在Linux系统中携带时间的文章&#xff1a;Java的jstat命令输出GC信息时携带时间信息&#xff08;Linux系统中&#xff09; 但是很多时候&#xff0c;我们都是在Windows系统中开发&#xff0c;可能有些人没有Linux环境&#xff0c;所以这篇文章就讲一下在Windows系统…

[论文精读]Multi-View Multi-Graph Embedding for Brain Network Clustering Analysis

论文原文&#xff1a;3504035.3504050 (acm.org) 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 省流版 1.1. 心得…

63 epoll服务器 (ET模式)

基于LT模式修改&#xff0c;并加入前面的应用层计算器&#xff0c;实现稍完整的服务器功能 1.修改tcp_socket.hpp&#xff0c;新增非阻塞读和非阻塞写接口 2.对于accept返回的new_sock加上EPOLLET这样的选项 注意&#xff1a;此代码暂时未考虑listen_sock ET的情况&#xff0c…

力扣高频SQL 50题(基础版)第三十九题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第三十九题1327.列出指定时间段内所有的下单产品题目说明实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第三十九题 1327.列出指定时间段内所有的下单产品 题目说明 表: Produc…

SQLite库笔记:API函数编程

本文主要介绍SQLite库的一些核心API函数&#xff0c;和实现数据库增删查改功能的C语言示例程序代码。 目录 1. API函数原型 1.1 sqlite3_open 1.2 sqlite3_close 1.3 sqlite3_free 1.4 sqlite3_errmsg 1.5 sqlite3_exec 1.6 sqlite3_get_table 1.7 sqlite3_free_table…

springboot废物回收管理商城-计算机毕业设计源码18221

基于Spring boot的废物回收管理商城 摘要 本研究基于Spring Boot框架设计并开发了一款废物回收管理商城系统&#xff0c;旨在有效整合废物回收资源&#xff0c;提高废物回收的效率和便捷性。通过对废物回收市场的调研与分析&#xff0c;结合现代互联网技术和物联网技术&#…

Docker Buildx 简介与安装指南

目录 1.Docker Buildx 简介 1. 引言 2. Docker Buildx 的背景和意义 3. Docker Buildx 的主要特性 4. 为什么选择 Docker Buildx 2.激活 Docker 实验性特性&#xff1a;一步设置 3.比如ARM架构下的Docker Buildx未自带 4.重启docker &#x1f310; 无论你是初学者还是经…

非递归的归并排序

我们之前讲的快速排序有非递归的写法&#xff0c;那么归并排序也有非递归写法&#xff0c;我们一起来研究一下吧。 快速排序的非递归算法是使用的手动搭栈的方法&#xff0c;将区间存入栈里面&#xff0c;然后再排序&#xff0c;但是这次的归并排序可以吗&#xff1f;大家都知…

WebLogic 8.x中间件监控指标解读

监控易是一款功能强大的IT监控系统&#xff0c;能够全面监控各类IT设施的运行状态&#xff0c;及时发现并解决潜在问题。针对WebLogic 8.x中间件的监控&#xff0c;监控易提供了一系列详尽的指标&#xff0c;确保WebLogic集群和应用的稳定运行。 在WebLogic集群监控方面&#x…

OSPF路由协议----开放式最短路径优先

一、为什么需要OSPF? 1、RIP以跳数评估的路由并非最优路径 传输时间T=2Mps/64Kbps=32s 如果选择S0/0传输,传输时间T=2Mps/2Mps+2Mps/2Mps+2Mps/2Mps=3s 时长大大缩短。 2、RIP的最大跳数为16,网络尺度小 RIP协议限制网络直径不能朝超过16跳,只适用于小型网。 3、RIP收…

登录谷歌账号时无法登录,提示“您正常是在一部Google无法识别的设备上登录”,原因和如何解决?

这段时间&#xff0c;有几个朋友联系GG账号服务&#xff0c;说她们在登录谷歌账号的时候&#xff0c;提示Google账号无法登录&#xff0c;提示&#xff1a;您正尝试在一部Google无法识别的设备上登录&#xff0c;我们没有足够的信息来验证您的身份。为了安全起见&#xff0c;您…

浦语提示词工程实践

第一次 -失败 修改后&#xff1a;

中缀与前缀表达式之间的转换

文章目录 中缀表达式转前缀表达式总结参考链接 中缀表达式转前缀表达式 前缀表达式&#xff0c;又称波兰表达式&#xff0c;是一种编写算术表达式的方法&#xff0c;其中运算符位于操作数之前。 下面给出一种中缀表达式转前缀表达式的方法&#xff0c;利用辅助栈。 其规责如下…

朱锐 | 生命图像中的时间和意识

本文载于《科学・经济・社会》2023 年第 41 卷第 2 期第 37~61 页 作者简介&#xff1a; 朱锐&#xff08;1968年10月—2024年8月1日&#xff09;&#xff0c;中国人民大学哲学院杰出学者、特聘教授&#xff0c;美国德州州立大学客座教授&#xff0c;主要从事神经哲学、心灵哲…

大学生编程入门指南:如何从零开始?

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 编程语言选择 &#x1f4da; 1. Python 2. JavaScript 3. Java 4. C/C 如何选择适合自己的编程语言&a…

人工智能深度学习系列—探索余弦相似度损失:深度学习中的相似性度量神器

文章目录 1. 背景介绍2. Loss计算公式3. 使用场景4. 代码样例5. 总结 1. 背景介绍 在机器学习和模式识别领域&#xff0c;评估样本间的相似性是一项基本而关键的任务。余弦相似度损失&#xff08;Cosine Similarity Loss&#xff09;作为一种衡量向量间相似度的损失函数&#…

TPAMI 2024 | 全新框架!深度学习可解释度量学习!

TPAMI 2024 | 全新框架&#xff01;深度学习可解释度量学习&#xff01; DIML: Deep Interpretable Metric Learning via Structural Matching 题目&#xff1a;DIML: 通过结构匹配的深度可解释度量学习 作者&#xff1a;Wenliang Zhao, Yongming Rao, Jie Zhou , and Jiwen…