Linux:动态库和静态库的编译与使用

目录

        1.前言

        2.静态链接库

        3.静态链接库生成步骤

        4.静态链接库的使用

        5.动态链接库

        6.动态链接库生成步骤

        7.动态链接库的使用

        8.动态链接库无法加载

        9.解决动态链接库无法加载问题


前言

        在《MinGW:从入门到链接库》博客中简单介绍了如何编译动态链接库和静态链接库,本篇博客将详细的对Linux下编译动态链接库和静态链接库以及使用进行讲解,刨析创建库文件的时候Linux做了哪些操作。本篇博客将从静态链接库讲起,再到动态链接库的讲解,并配上演示图片


静态链接库

        静态链接库是一组编译后的代码和资源,它们在编译时被整合到最终的可执行文件中。其静态链接库在不同系统的命名规则如下:

        1..Linux下的动态链接库的命名规则为lib+文件名+.a,所以Linux中以.a结尾的文件,一般可以视为静态链接库的文件

示例:libWild.a

        2.Windows下的动态链接库的命名规则为lib+文件名+.lib,所以以.lib结尾的文件,一般可以视为静态链接库的文件

示例:libWild.lib

        静态链接库的优缺点如下

                优点

                        1.库代码已经包含在可执行文件中,不需要携带额外的库文件

                        2.执行速度快,因为操作系统不需要在运行时解析外部库

                缺点

                        1.增加了可执行文件的大小,因为其静态链接库包含了所有代码

                        2.如果库更新,需要重新编译整个应用程序,编译时间长


静态链接库生成步骤

        在了解了静态链接库的特点以及不同系统下的命名方式后,我们需要着手生成一个静态链接库文件:

        1.使用-c命令生成汇编文件

//使用-c命令生成汇编文件
g++ -c -I "头文件路径" *.cpp

        2.使用ar命令打包生成静态链接库

//使用ar命令生成静态链接库
ar rcs 静态链接库名.a 汇编文件.o
 
//ar rcs libfun.a fun.o
//其中r代表替换.o文件,c代表库不存在则生成,s代表生成索引文件

        可参考下图生成静态链接库:

图1.生成静态链接库


静态链接库的使用

        当使用命令生成一个可用的静态链接库后,我们需要将其源文件与静态链接库放到同一个目录中,然后根据头文件编写代码, 对静态库中的函数进行调用

        1.将源文件与静态链接库链接产生可执行文件       

//方法1
g++ 源文件.o -o 可执行文件名 静态链接库路径
 
//方法2
g++ 源文件.o -o 可执行文件名 -L静态链接库路径
 
//方法3,其中静态链接库名为除去lib和.a的名称
//例如libfun.a,其静态链接库名就为fun
g++ 源文件.o -o 可执行文件名 -L静态链接库路径 -l静态链接库名

图2.多种方法生成静态链接库可执行文件

        PS:如果提示找不到头文件的定义,需要使用-L和-l命令,其含义如下:

-L: 指定库所在的路径
-l: 指定库的名字, 需要去掉前缀lib和后缀.a

示例:g++ Code.o -o Code -L ./ -l fun
//其中fun为静态链接库libfun.a


动态链接库

        动态链接库在程序运行时被加载,而不是在编译时。它允许多个程序共享同一份库代码。其命名规则如下:

        1..Linux下的动态链接库的命名规则为lib+文件名+.so,所以Linux中以.so结尾的文件,一般可以视为动态链接库的文件

示例:libWild.so

        2.Windows下的动态链接库的命名规则为lib+文件名+.dll,所以以.dll结尾的文件,一般可以视为动态链接库的文件

示例:libWild.dll

        动态链接库的优缺点如下:

                优点

                        1.减少了内存占用,因为多个程序可以共享同一份库代码

                        2.库的更新只需要更新DLL文件本身,不需要重新编译使用该库的应用程序

                        3.可以动态加载和卸载,提供更高的灵活性

                缺点

                        1.运行时需要加载库,可能会稍微增加启动时间

                        2.如果库文件被其他程序占用或损坏,可能会导致程序无法正常运行


动态链接库生成步骤

        在了解了动态链接库的特点以及不同系统下的命名方式后,我们需要着手生成一个动态链接库文件:

        1.使用-c命令生成汇编文件

//使用-c命令生成汇编文件
g++ -c -I "头文件路径" *.cpp

        2.使用-shared命令生成动态链接库

//使用-shared命令生成动态链接库
g++ -o 动态链接库.dll -I "头文件路径" -fPIC -shared *.cpp
 

图3.生成动态链接库


动态链接库的使用

        当使用命令生成一个可用的动态链接库后,我们需要将其源文件与动态链接库放到同一个目录中,然后根据头文件编写代码, 对动态库中的函数进行调用

        1.将源文件与静态链接库链接产生可执行文件   

//方法1
g++ 源文件.o -o 可执行文件名 动态链接库路径
 
//方法2
g++ 源文件.o -o 可执行文件名 -L动态链接库路径
 
//方法3,其中动态链接库名为除去lib和.dll的名称
//例如libfun.dll,其静态链接库名就为fun
g++ 源文件.o -o 可执行文件名 -L动态链接库路径 -l动态链接库名

图4.多种方法生成动态链接库可执行文件

        PS:倘若出现未定义的头文件等错误,则可以参考静态链接库生成可执行文件的方法,使用-L与-l命令指定库地址


动态链接库无法加载

        首先为啥这种无法加载的问题会出现在动态链接库?而不是静态链接库。是由于在生成可执行文件时,静态链接库会被打包到可执行程序中。当程序执行时,静态链接库库中的代码也会加载到系统的内存当中,因此不会出现静态链接库找不到无法被加载的问题

        而动态链接库在打包时只是检测库文件是否存在,存在则打包,不存在则不打包。所以动态链接库并没有被打包到可执行文件中,只是在文件中记录了动态链接库的名字。所以当程序执行时,会存在动态链接库无法加载的问题


解决动态链接库无法加载问题

        在Linux系统中,我们可以使用动态链接器来解决这个问题。动态链接器是一个在程序运行时负责链接程序与动态链接库的程序,其寻找链接库的步骤如下:

                1.编译时指定路径:如果编译时通过特定的编译器选项(如在Linux中的-Wl,-rpath)指定了库的运行时搜索路径,动态链接器会首先在这些路径中搜索库

                2.环境变量:动态链接器会检查环境变量来确定库的搜索路径。例如,在Linux系统中,LD_LIBRARY_PATH环境变量可以添加额外的库搜索路径;在Windows系统中,PATH环境变量用于搜索.dll文件

                3.标准库目录:操作系统会预定义一些标准目录来存放系统级的库。例如,在Linux中,/lib/usr/lib是常见的库目录;在Windows中,系统目录(如C:\Windows\System32)是搜索.dll文件的地方

                4.可执行文件所在目录:动态链接器会搜索可执行文件所在的目录

        解决方法如下:

                1: 将库路径添加到环境变量LD_LIBRARY_PATH中

                        1.找到相关的配置文件

~/.bashrc:用户路径,只对当前用户有效
/etc/profile:系统路径,对所有用户有效

                        2.修改配置文件

#添加动态链接库路径
export LD_LIBRARY_PATH =$LD_LIBRARY_PATH :动态链接库的绝对路径

图5.将库路径添加到环境变量LD_LIBRARY_PATH

                        3.执行更新命令

source ~/.bashrc    //用户路径
source /etc/profile //系统路径

//source命令用于执行指定文件

                2.更新/etc/ld.so.cache文件

                        1.打开ld.so.cache文件

sudo vim /etc/ld.so.conf

                        2.更新 /etc/ld.so.conf中的数据到 /etc/ld.so.cache 中

sudo ldconfig   

图6.更新/etc/ld.so.cache文件


        PS:关于动态链接库和静态链接库的生成与使用还需要更多的实践才能更灵活的运用,所以不要停留在纸上谈兵的阶段,计算机专业并不是什么文科,不需要通篇背诵,多实操,多练,多发现问题,多解决问题

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python - pandas常用计算函数

文中所用数据集有需要的可以私聊我获取 学习目标 知道排序函数nlargest、nsmallest和sort_values的用法 知道Pandas中求和、计数、相关性值、最小、最大、平均数、标准偏差、分位数的函数使用 1 排序函数 导包并加载数据集 import pandas as pd ​ # 加载csv数据, 返回df对…

MySQL之多表查询—行子查询

一、引言 上篇博客学习了列子查询。 接下来学习子查询中的第三种——行子查询。 行子查询 1、概念 子查询返回的结果是一行&#xff08;当然可以是多列)&#xff0c;这种子查询称为行子查询。 2、常用的操作符 、 <> (不等于) 、IN 、NOT IN 接下来通过一个需求去演示和…

系统思考—心智模式

凯恩斯说&#xff1a;“介绍新观念倒不是很难&#xff0c;难的是清除那些旧观念。”在过去的任何一年&#xff0c;如果你一次都没有推翻过自己最中意的想法&#xff0c;那么你这一年就算浪费了。旧观念像是根深蒂固的杂草&#xff0c;即使在新知识的光照下&#xff0c;也需要时…

stream 流的一些底层实现原理

闭包 闭包的底层实现?外层的变量成为方法的一部分会生成一个lambda方法&#xff0c;将源本的2个参数转化3个参数此时变量就成为了方法的一部分值是如何传递的呢?会有一个专门的类用于存储此变量的值 流的切分后再并行 数组或者是集合&#xff0c;需要用到一个可切分的迷代器这…

如何一键拷贝PPT中的所有文字?

有时我们可能需要引用PPT的文字&#xff0c;但一个幻灯片一个幻灯片拷贝很是麻烦&#xff0c;我们想一键拷贝PPT中所有幻灯片中的内容&#xff08;最近我就遇到了这个需求&#xff09;。今天就来讲讲这个一键拷贝的技巧。因为大家可能会遇到同样的问题&#xff0c;所以在此记录…

[Vue-常见错误]浏览器显示Uncaught runtime errors

文章目录 错误描述正确写法具体如下 错误描述 当前端代码发生错误时&#xff0c;浏览器中出现以下错误提示。 正确写法 显然这不是我们所期望的&#xff0c;在vue.config.js中配置如下设置关闭Uncaught runtime errors显示 devServer: {client: {overlay: false}具体如下 …

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…

二叉查找树详解

目录 二叉查找树的定义 二叉查找树的基本操作 查找 插入 建立 删除 二叉树查找树的性质 二叉查找树的定义 二叉查找树是一种特殊的二叉树&#xff0c;又称为排序二叉树、二叉搜索树、二叉排序树。 二叉树的递归定义如下&#xff1a; &#xff08;1&#xff09;要么二…

知识图谱的应用---智能电网

文章目录 智能电网典型应用 智能电网 智能电网以物理电网为基础&#xff0c;将现代先进的传感测量技术、通讯技术、信息技术、计算机技术和控制技术与物理电网高度集成而形成的新型电网。它以充分满足用户对电力的需求和优化资源配置、确保电力供应的安全性、可靠性和经济性、满…

代码随想录-Day28

93. 复原 IP 地址 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0c;但是 “0.011.255…

业务扩张阶段

和之前相比就是服务器的数量增多了 业务系统增多了 每个业务的用户也在增多 采购费用和电费挺多 选课系统一年只用几次&#xff0c;平时不用太浪费服务器的资源&#xff0c;那么怎么才能提高服务器资源的利用率呢 在一个服务器上部署多个不同的业务系统能行吗 不太行&…

TransformerFAM:革新深度学习的新型注意力机制

深度学习领域的一项突破性技术——Transformer架构&#xff0c;已经彻底改变了我们处理序列数据的方式。然而&#xff0c;Transformer在处理长序列数据时面临的二次复杂度问题&#xff0c;限制了其在某些应用场景下的潜力。针对这一挑战&#xff0c;研究者们提出了一种名为Tran…

Qwen2大模型微调入门实战(完整代码)

Qwen2是通义千问团队的开源大语言模型&#xff0c;由阿里云通义实验室研发。以Qwen2作为基座大模型&#xff0c;通过指令微调的方式实现高准确率的文本分类&#xff0c;是学习大语言模型微调的入门任务。 指令微调是一种通过在由&#xff08;指令&#xff0c;输出&#xff09;对…

使用vite从0开始搭建vue项目

使用Vite从0开始创建vue项目 第一步&#xff1a;创建项目目录 mkdir vue-demo -创建目录 cd vue-demo --进入项目 npm init -y --生成package.json文件 第二步&#xff1a;安装vite、typescript--ts、vue、vitejs/plugin-vue--对单文件组件、热重载、生产优化的支持 pnpm…

【Python】探索 One-Class SVM:异常检测的利器

我已经从你的 全世界路过 像一颗流星 划过命运 的天空 很多话忍住了 不能说出口 珍藏在 我的心中 只留下一些回忆 &#x1f3b5; 牛奶咖啡《从你的全世界路过》 在数据科学和机器学习领域&#xff0c;异常检测&#xff08;Anomaly Detection&#xff09;是…

工业通讯现场中关于EtherCAT转TCPIP网关的现场应用

在当今工业自动化的浪潮中&#xff0c;EtherCAT技术以其高效、实时的特性成为了众多制造业的首选。然而&#xff0c;随着工业互联网的发展&#xff0c;对于数据的远程访问和云平台集成的需求日益增长&#xff0c;这就需要将EtherCAT协议转化为更为通用的TCP/IP协议。于是开疆智…

【MMU】——MMU 权限控制

文章目录 权限控制内存访问权限内存类型XN execute neverDomain 权限控制 内存访问权限 内存类型 TEX C B bit 控制信息 XN execute never 不可执行区域&#xff0c;例如设备地址空间通常标记为不可执行区域&#xff0c;如果有指令预取访问了该空间&#xff0c;就会触发指令…

CVE-2022-4230

CVE-2022-4230 漏洞介绍 WP Statistics WordPress 插件13.2.9之前的版本不会转义参数&#xff0c;这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下&#xff0c;具有管理选项功能 (admin) 的用户可以使用受影响的功能&#xff0c;但是该插件有一个设置允许低权限用…

快速入门Linux及使用VSCode远程连接Linux服务器

在当前的技术环境中&#xff0c;Linux操作系统因其强大的功能和灵活性而广受欢迎。无论你是开发人员、系统管理员还是技术爱好者&#xff0c;学习Linux都是提升技术技能的重要一步。本文将介绍如何快速入门Linux&#xff0c;并使用Visual Studio Code&#xff08;VSCode&#x…

【RAG入门教程03】Langchian框架-文档加载

Langchain 使用文档加载器从各种来源获取信息并准备处理。这些加载器充当数据连接器&#xff0c;获取信息并将其转换为 Langchain 可以理解的格式。 LangChain 中有几十个文档加载器&#xff0c;可以在这查看https://python.langchain.com/v0.2/docs/integrations/document_lo…