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

news2025/1/18 16:49:25

目录

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

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

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

相关文章

快速安装Windows和Ubuntu双系统

一、参考资料 用UltraISO制作Ubuntu16.04 U盘启动盘 DiskPart Command-Line Options 二、相关介绍 1. MBR和GPT分区模式 MBR分区模式 MBR最大仅支持2TB磁盘,超过2TB不可识别。 MBR(Master Boot Record),即硬盘的主引导记录分…

统计信号处理基础 习题解答10-8

题目 一个随机变量具有PDF 。希望在没有任何可用数据的情况下估计的一个现实。为此提出了使最小的MMSE估计量,其中期望仅是对求的。证明MMSE估计量为。将你的结果应用到例10.1,当把数据考虑进去时,证明最小贝叶斯MSE是减少的。 解答 在贝叶…

python -- series和 DataFrame增删改数据

学习目标 知道df添加新列的操作 知道insert函数插入列数据 知道drop函数删除df的行或列数据 知道drop_duplicates函数对df或series进行数据去重 知道unique函数对series进行数据去重 知道apply函数的使用方法 1 DataFrame添加列 注意:本文用到的数据集在文章顶部 1.1 直…

Servlet基础(续集)

Servlet原理 Servlet是由Web服务器调用&#xff0c;Web服务器在收到浏览器请求之后&#xff0c;会&#xff1a; Mapping问题 一个Servlet可以指定一个映射路径 <servlet-mapping><servlet-name>hello</servlet-name><url-pattern>/hello</url-pa…

物联网8大协议介绍及对比

一.物联网主流协议介绍 1.MQTT 协议 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;即消息队列遥测传输。 MQTT 协议最初是在 1999 年由 IBM 公司开发的&#xff0c;用于将石油管道上的传感器与卫星相连接。2014 年正式成为 OASIS 开放标准。 MQTT 使用…

Element UI上传图片和PDF,支持预览,并支持复制黏贴上传

背景 如上图&#xff0c;使用Element UI的el-upload组件&#xff0c;并且预览的时候可以展示图片和PDF格式文件&#xff1b; 做法 index.vue <template><div><el-uploadv-model"diaForm.list":limit"5":on-exceed"handleExceed"…

使用AutoGen框架进行多智能体协作:AI Agentic Design Patterns with AutoGen

AI Agentic Design Patterns with AutoGen 本文是学习https://www.deeplearning.ai/short-courses/ai-agentic-design-patterns-with-autogen/ 这门课的学习笔记。 What you’ll learn in this course In AI Agentic Design Patterns with AutoGen you’ll learn how to buil…

vue+vscode 快速搭建运行调试环境与发布

1.安装node.js Node.js — Run JavaScript Everywhere 默认不断next 2.更换镜像地址 运行-cmd 执行以下代码安装 npm config set registry https://registry.npmmirror.com 检查node.js和镜像是否是否成功 node -v npm -v npm config get registry 3.安装打包工具 …

【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;死信队列 RabbitMQ的工作模式 死信队列的工作模式 二、&#x1f349;RabbitMQ相关的安装 三、&#x1f34e;SpringBoot引入RabbitMQ 1.引入依赖 2.创建队列和交换器 2.1 变量声明 2.2 创建…

Java采取擦除式泛型到底兼容了什么场景?

在开始前刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;Java擦除式泛型是一个妥协,…

高光谱图像聚类的像素-超像素对比学习与伪标签校正

Pixel-Superpixel Contrastive Learning and Pseudo-Label Correction for Hyperspectral Image Clustering 文章目录 Pixel-Superpixel Contrastive Learning and Pseudo-Label Correction for Hyperspectral Image Clustering摘要引言相关方法对比学习 方法超像素对比学习像素…

【Flask开发实战】首页模板

一、前言 前面我们已经完成登录页面的设定&#xff0c;登录后临时调转到“hello flask”的界面。现在我们根据实际首页的设计需要&#xff0c;来完成首页相关内容的开发。一般系统首页会放一些分析数据&#xff0c;多以图表的方式展示&#xff0c;方便使用者了解信息。以防火墙…

JavaScript事件监听之其它事件(页面加载事件、元素滚动事件、页面尺寸事件、M端事件)

目录 1. 页面加载事件(load、DOMContentLoaded)2. 元素滚动事件(scroll)3. 页面尺寸事件3.1 resize3.2 获取元素宽高3.3 获取元素位置(offsetLeft和offsetTop、getBoundingClientRect) 4. M端事件 1. 页面加载事件(load、DOMContentLoaded) load事件&#xff1a; 使用场景: 等…

MyBatis二级缓存开启条件

MyBatis缓存为俩层体系。分为一级缓存和二级缓存。 一级缓存&#xff1a; 一级缓存默认开启&#xff0c;一级缓存的作用域是SqlSession级别的&#xff0c;这意味着当你更换SqlSession之后就不能再利用原来的SqlSession的一级缓存了。不同的SqlSession之间的一级缓存是隔离的。…

基础概念解析:SOCKS5代理究竟是什么?SOCKS5代理ip使用场景有哪些?

在当今数字化时代&#xff0c;网络安全和隐私保护已成为我们日常生活中不可忽视的问题。随着网络攻击手段的日益复杂&#xff0c;如何安全地访问互联网资源成为了一个亟待解决的问题。SOCKS5代理作为一种先进的网络协议&#xff0c;为我们提供了解决这一问题的有效方案。 本文…

实用的 C 盘搬家软件

一、简介 1、一款专门用于 Windows 系统的文件夹移动工具&#xff0c;它允许用户将程序或游戏的安装文件夹从一台驱动器移动到另一台驱动器&#xff0c;或者同一个驱动器内的不同路径&#xff0c;而无需重新安装或破坏现有的程序安装。 二、下载 1、下载地址&#xff1a; 官网链…

3-1RT-Thread时钟管理

这里写自定义目录标题 时钟节拍是RT thread操作系统的最小时间单位。 第一个功能&#xff0c;rt tick值自动加1&#xff0c;在RT thread当中通过RT_USING_SMP定义了多核和单核的场景。第二个功能&#xff0c;检查当前线程的时间片&#xff0c;首先获取当前线程&#xff0c;将当…

AI 写高考作文丨10 款大模型 “交卷”,实力水平如何?

前言 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再是遥不可及的未来科技&#xff0c;而是逐渐融入我们日常生活的实用工具。从智能语音助手到自动驾驶汽车&#xff0c;从智能家居系统到精准医疗诊断&#xff0c;AI技术正以其强大的计算能力和数…

端午搞个零花钱,轻松赚取创业的第一桶金!2024最受欢迎的创业项目,2024新的创业机会

好好的端午节&#xff0c; 净给我添堵&#xff01; 本来我打算在端午节愉快的玩耍&#xff0c; 结果一大早起床却看到舍友在给一堆设备充电&#xff0c; 然后装的整整齐齐&#xff0c; 满满一书包。 我好奇他小子这是要干嘛&#xff1f; 不会是打算今天回去给亲朋好友准备…

Centos7 安装配置SFTP

Centos7安装配置SFTP 更新源安装 OpenSSH 服务启动服务设置为开机自启动新建一个用户 (sftpuser为你要设置的用户的用户名)编辑配置文件设置sftp用户的根目录重启SSH服务代码实现 由于最近工作中需要实现动态上传文件到帆软服务器&#xff0c;但是帆软没有提供相关API&#xff…