Linux 的静态库和动态库

本文目录

  • 一、静态库
    • 1. 创建静态库
    • 2. 静态库的使用
  • 二、动态库
    • 1. 为什么要引入动态库呢?
    • 2. 创建动态库
    • 3. 动态库的使用
    • 4. 查看可执行文件依赖的动态库

  

一、静态库

   在编译程序的链接阶段,会将源码汇编生成的目标文件.o与引用到的库(包括静态库)的二进制文件一起链接打包到最终的可执行文件中。

静态库常以.a.lib为后缀。
   静态库命名规范:lib[name].a,其中lib是静态库前缀,中间[name]为静态库名称,最后.a为静态库后缀。例如:libaddfunc.a,其中addfunc才是静态库的名称。

1. 创建静态库

   在使用创建静态库前,为了使得工程目录更加清晰,我们创建三个文件夹lib(存放.h文件)、src(存放.c文件)、debug(存放.o文件)

(1)编写库文件。
fun1.c

#include "stdio.h"int add(int a, int b)
{return a+b;
}

fun1.h

#include "stdio.h"int add(int a, int b);

将编写好的库文件存放到不同的文件夹里。

(2)将库文件编译为目标文件(.o)
  使用命令:gcc -c ./src/fun1.c -o ./debug/fun1.o,在debug目录下生成fun1.o目标文件。

(3)创建封装静态库
  使用ar工具,并添加命令 rcs,将debug文件夹里的所有的.o文件进行封装为静态库libaddfunc.a
  如:ar rcs libaddfunc.a ./debug/*.o。此时libaddfunc.a就是静态库。其中addfunc是静态库的名称。
在这里插入图片描述

2. 静态库的使用

(1)编写main.c源码文件

main.c

#include "fun1.h"
#include "stdio.h"int main()
{int a=8;int b=10;int sum=0;sum=add(a,b);printf("%d\n"sum);
}

(2)编译源码时链接静态库,生成可执行文件。
  命令:gcc main.c -o main -I ./lib -L ./ -l addfunc
   -I ./lib :表示头文件所在的路径。
   -L ./ :表示静态库所在的路径,此处为当前路径。
   -l addfunc:表示要连接的静态库名称,addfunc为静态库名称。

在这里插入图片描述

(3)运行可执行文件。
在这里插入图片描述

二、动态库

   在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入。

动态库常以.so.dll为后缀。
   动态库命名规范:lib[name].a,其中lib是动态库前缀,中间[name]为动态库名称,最后.so为动态库后缀。例如:libsubfunc.so,其中subfunc才是动态库的名称。

1. 为什么要引入动态库呢?

   答:因为在静态库存在一个弊端,就是当我们对库文件添加或修改了部分内容,将其生成新的静态库文件后,我们需要将所有使用该库文件的程序文件都要重新编译。因为当静态库修改后,其二进制文件也会改变。静态库在程序编译链接阶段,将字节的二进制文件一同打包到程序的可执行文件中。所以静态库改变后,需要将使用了该静态库的可执行文件都需要重新进行编译。这样就会特别繁琐,所以引入了动态库。
   动态库只会在程序运行时载入。动态库作为一个独立的文件存在于系统中,可以被多个文件共享使用,当动态库进行维护时,只需要将新的动态库文件替换旧的动态库文件即可,不需要对使用动态库的文件程序重新编译,这就是动态库的好处。

2. 创建动态库

举例使用的库文件我们使用上述静态库时的库文件。同样存放到不同的文件夹中。

(1)将库文件生成目标文件(.o)

  使用命令:gcc -fpic -c ./src/fun1.c -o ./debug/fun1.o,在debug目录下生成fun1.o目标文件。

(2)生成动态库–共享库
  使用命令:gcc -shared ./debug/*.o -o libfun2.so。其中libfun2.so为动态链接库,也称共享库。
在这里插入图片描述

3. 动态库的使用

(1)编译源码,生成可执行文件
使用命令:gcc main.c -o main -I ./lib -L ./ -l fun2
   -I ./lib :表示头文件所在的路径。
   -L ./ :表示动态库所在的路径,此处为当前路径。
   -l addfunc:表示要连接的动态库名称。
在这里插入图片描述
  虽然这里我们也指定了动态库的路径,但是动态库在编译可执行文件时并不会进行链接,而是在执行时才会进行链接!所以当我们维护动态库时,才不会对所使用动态库的文件进行重新编译。

(2)将库路径添加到系统加载器
   生成的可执行文件,当我们执行时,会发生以下错误,原因是我们虽然告诉了编译器库文件和头文件的路径所在位置,但是当编译器编译好后,就与编译器无关了;当我们执行(运行)可执行程序时,是由加载器来完成的。所以我们需要在运行时,告诉系统库文件在哪里。
在这里插入图片描述

 方法一:将libfun2.so添加到/usr/lib/下, 使用命令:sudo cp libfun2.so /usr/lib/进行添加。不推荐!
 方法二:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/qjl , LD_LIBRARY_PATH环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径。
在这里插入图片描述

(3)运行可执行文件
在这里插入图片描述

4. 查看可执行文件依赖的动态库

使用命令:ldd 可执行文件
在这里插入图片描述

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

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

相关文章

Java学习第01天-Java及开发序言

目录 Java技术体系 Java安装 Hello World程序 JDK & JRE IDEA安装和使用 Java技术体系 技术体系说明Java SE(Java Standard Edition):标准版 Java技术的核心和基础Java EE(Java Enterprise Edition):企业版企业级应用开发的一套解决方案Java M…

设计模式 --6组合模式

文章目录 组合模式应用场景组合模式概念组合模式结构图透明方式和安全方式什么时候使用组合模式公司管理系统使用 组合模式来构架组合模式的好处 组合模式应用场景 整体和部分可以被一致性对待 比如人力资源部 财务部的管理功能可以复用于分公司的功能 可以引入一种 树状的结构…

llama_index微调BGE模型

微调模型是为了让模型在特殊领域表现良好,帮助其学习到专业术语等。 本文采用llama_index框架微调BGE模型,跑通整个流程,并学习模型微调的方法。 一、环境准备 Linux环境,GPU L20 48G,Python3.8.10。 pip该库即可。 二、数据准备 该框架实现了读取各种类型的文件,给…

基于Spring Boot的校园博客系统设计与实现

基于Spring Boot的校园博客系统设计与实现 开发语言:Java框架:springbootJDK版本:JDK1.8数据库工具:Navicat11开发软件:eclipse/myeclipse/idea 系统部分展示 系统功能界面图,在系统首页可以查看首页、文…

【webrtc】MessageHandler 5: 基于线程的消息处理:以PeerConnection信令线程为例

peerconn的信令是通过post 消息到自己的信令线程消息来处理的PeerConnectionMessageHandler 是具体的处理器G:\CDN\rtcCli\m98\src\pc\peer_connection_message_handler.hMachinery for handling messages posted to oneself PeerConnectionMessageHandler 明确服务于 signalin…

使用xshell工具连接ubuntu的root账户被拒绝的解决方法

问题描述: 我在使用xshell工具远程连接Ubuntu虚拟机的过程中,如果连接的是的普通用户则xshell工具可以正常连接,但是当我向连接ubuntu系统的root用户,即便是密码输入正确但还是不能连接成功。不能连接成功的截图如下: …

requests库进行接口请求

请求的常规写法 requests.post() 、requests.get() 从中可以看出: 必填参数: url可缺省参数: data,json等、关键字参数 **kwargs 如下进行了一个post请求的登录,且请求体在body中 知识点1 当为post请求时&#xff1…

python数据可视化:创建多个子图 matplotlib.pyplot.subplot()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 python数据可视化: 创建多个子图 matplotlib.pyplot.subplot() 请问关于以下代码表述正确的选项是? import matplotlib.pyplot as plt print("【执行】plt.subp…

Docker部署RabbitMQ与简单使用

官网地址: Messaging that just works — RabbitMQ 我的Docker博客:Docker-CSDN博客 1.结构 其中包含几个概念: **publisher**:生产者,也就是发送消息的一方 **consumer**:消费者,也就是消费消息的一方 …

【DeepL】菜鸟教程:如何申请DeepL免费API并使用Python的DeepL

前言 在这篇技术博文中,我们将介绍如何利用DeepL的强大功能,通过其免费API在Python项目中实现高质量的文本翻译。我们将从基础开始,解释DeepL是什么,它的用途,如何申请免费API,以及如何在Python中使用DeepL库。 什么是DeepL? DeepL是一个基于人工智能的翻译服务,它以…

【langchain】快速封装替换自定义LLM(基于自定义API或本地模型)

1. 引言 你可能已经注意到,LLM时代下的许多项目(特别是Github上的论文项目、工程项目)都要求我们设置OpenAI的API Key,就像这样: os.environ["OPENAI_API_KEY"] "sk-"from langchain_openai im…

【多模态大模型】AI对视频内容解析问答

文章目录 1. 项目背景2. 直接对视频进行解析进行AI问答:MiniGPT4-Video2.1 MiniGPT4-Video效果 3. 对视频抽帧为图片再进行AI问答3.1 视频抽帧3.2 图片AI问答3.2.1 阿里通义千问大模型 Qwen-vl-plus3.2.2 Moonshot 1. 项目背景 最近在做一个项目,需要使用AI技术对视…