静态库和动态库制作

文章目录

  • 前言
  • 一、静态库和动态库介绍
    • 1、静态库
    • 2、动态库
  • 二、静态库的制作及使用
    • 1、准备好源码
    • 2、编译源码生成 .o 文件
    • 3、制作静态库
    • 4、使用静态库
  • 三、动态库的制作及使用
    • 1、生成位置无关的 .o 文件
    • 2、制作动态库
    • 3、使用动态库
    • 4、指定动态库路径并使其生效
  • 四、对比
    • 1、静态库优缺点
    • 2、动态库优缺点


前言

我们在编写代码的时候经常用到已有的接口,他们是以库的形式提供给我们使用的,而常见形式有两种,一种常以 .a 为后缀,为静态库;另一种以 .so 为后缀,为动态库。所谓的静态、动态指的是链接的过程。


一、静态库和动态库介绍

1、静态库

程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库。

静态库在文件中静态展开,所以有多少文件就展开多少次,非常吃内存,100M 展开 100 次,就是 10G,但是这样的好处就是静态加载的速度快。
在这里插入图片描述

2、动态库

程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

使用动态库会将动态库加载到内存,10 个文件也只需要加载一次,然后这些文件用到库的时候临时去加载,速度慢一些,但是很省内存。
在这里插入图片描述

二、静态库的制作及使用

静态库的名字是以 lib 开头,以 .a 结尾,例:libmylib.a

静态库生成的指令:

ar rcs libmylib.a file1.o

1、准备好源码

test.c

#include <stdio.h>
#include "sub.h"int main(int argc, char *argv[])
{int i = 6, j = 3;int k;printf("main fun! && i = %d\n", i);k = sub_fun(i, j);printf("k = %d\n", k);return 0;
}

sub.c

#include <stdio.h>int sub_fun(int a, int b)
{printf("sub fun!\n");return a - b;
}

sub.h

int sub_fun(int, int);

2、编译源码生成 .o 文件

gcc -c sub.c -o sub.o

在这里插入图片描述

3、制作静态库

在这里插入代码片

在这里插入图片描述

4、使用静态库

gcc test.c libmymath.a -o test
./test

在这里插入图片描述
test.c 文件仅有 213 字节,而 test 文件有 16K 大小,所以静态库使用时,是直接编译到文件里面的。
在这里插入图片描述

三、动态库的制作及使用

动态库的名字是以 lib 开头,以 .so 结尾,例:libmylib.so

1、生成位置无关的 .o 文件

gcc -c sub.c -o sub.o -fPIC

在这里插入图片描述
使用 -fPIC 这个参数过后,生成的函数就和位置无关,挂上 @plt 标识,等待动态绑定

2、制作动态库

gcc -shared -o libmymath.so sub.o

在这里插入图片描述

3、使用动态库

  • -l :指定库名
  • -L :指定库路径
gcc test.c -o test -l mymath -L ./
./test

在这里插入图片描述
出错原因分析:

  • 连接器: 工作于链接阶段,工作时需要 -l 和 -L
  • 动态链接器: 工作于程序运行阶段,工作时需要提供动态库所在目录位置

解决办法:指定动态库路径并使其生效,然后再执行文件

4、指定动态库路径并使其生效

通过环境变量指定动态库所在位置: export LD_LIBRARY_PATH=动态库路径

export LD_LIBRARY_PATH=./
./test

在这里插入图片描述
当关闭终端,再次执行 test 时,又报错。
在这里插入图片描述
这是因为,环境变量是进程的概念,关闭终端之后再打开,是两个进程,环境变量发生了变化。
要想永久生效,需要修改 bash 的配置文件: vi ~./bashrc

永久生效方法:

  • vi ~/.bashrc
  • 写入 export LD_LIBRARY_PATH=动态库路径 保存
  • source ~/.bashrc,再重启终端 —> 让修改后的 .bashrc 生效
  • 执行 ./test

在这里插入图片描述

四、对比

1、静态库优缺点

  • 静态库的加载速度快
  • 发布程序无需提供静态库,移植方便
  • 消耗系统资源,浪费内存
  • 更新、部署和发布麻烦

2、动态库优缺点

  • 可以实现进程间的资源共享
  • 更新、部署、发布简单
  • 可以控制何时加载动态库
  • 加载速度比较慢
  • 发布程序时需要提供依赖的动态库

我的qq:2442391036,欢迎交流!


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

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

相关文章

链表OJ详解

&#x1f495;人生不满百&#xff0c;常怀千岁忧&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;链表oj详解 题目一&#xff1a;移除元素 题目要求&#xff1a; 画图分析&#xff1a; 代码实现&#xff1a; struct ListNode* removeElements(struct List…

Linux实用命令合集

适用于CentOS7系统&#xff0c;其他系统有些命令不支持 yum install epel-release 失败 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo vi/vim检索关键字 命令模式:/****"n"可以跳转到下一个关键字位置 cat 查看配置文件不显示…

Redis 6.5 服务端开启多线程源码

redis支持开启多线程&#xff0c;只有从socket到读取缓冲区和从输出缓冲区到socket这两段过程是多线程&#xff0c;而命令的执行还是单线程&#xff0c;并且是由主线程执行 借鉴&#xff1a;【Redis】事件驱动框架源码分析&#xff08;多线程&#xff09; 一、main启动时初始化…

第4章:决策树

停止 当前分支样本均为同一类时&#xff0c;变成该类的叶子节点。当前分支类型不同&#xff0c;但是已经没有可以用来分裂的属性时&#xff0c;变成类别样本更多的那个类别的叶子节点。当前分支为空时&#xff0c;变成父节点类别最多的类的叶子节点。 ID3 C4.5 Cart 过拟合 缺…

超导热催生meme,换汤不换药的投机轮回

文/章鱼哥 出品/陀螺财经 币圈对炒作meme概念的热情从未消亡过。 随着一种名为LK-99的物质被发现&#xff0c;围绕超导的兴奋不仅激发了科学界&#xff0c;加密货币相关概念也与之沸腾。不出所料&#xff0c;与此前围绕元宇宙、AI大肆炒作一样&#xff0c;许多meme代币已经出现…

Spring 使用注解开发、代理模式、AOP

使用注解开发 在Spring4之后&#xff0c;要使用注解开发&#xff0c;必须要保证AOP的包导入了 项目搭建&#xff1a; 在配置文件中导入约束&#xff0c;增加注解支持 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.spri…

华为新版ENSP PRO模拟器测评:性能表现与功能扩展一览

一、引言 在网络领域不断涌现的新技术和复杂的网络拓扑要求&#xff0c;推动了网络设备模拟器的持续发展和创新。华为作为一家领先的通信技术解决方案提供商&#xff0c;不断致力于为网络工程师和技术从业人员提供更优秀的仿真环境。最近&#xff0c;华为推出了ensp pro模拟器的…

html 计算器界面

其他链接&#xff1a; https://www.freecodecamp.org/news/how-to-build-an-html-calculator-app-from-scratch-using-javascript-4454b8714b98/ https://codepen.io/pen/tour/welcome/start 下面展示一些 内联代码片。 <!DOCTYPE html> <html lang"en">…

苹果正在测试新款Mac mini:搭载M3芯片 配备24GB大内存

据悉苹果目前正在测试新的Mac机型&#xff0c;亮点是采用最新的M3芯片。 据报道&#xff0c;首款搭载M3芯片的设备应该是13英寸的MacBook Pro和重新设计的MacBook Air&#xff0c;Mac mini机型并不在名单上。 M3和M2同样拥有最多8个核心&#xff0c;分别为4个性能核和4个能效核…

MySQL高阶知识点(一)一条SQL【更新】语句是如何执行的

一条SQL【更新】语句是如何执行的 首先&#xff0c;可以确定的说&#xff0c;【查询】语句的那一套流程&#xff0c;【更新】语句也是同样会走一遍&#xff0c;与查询流程不一样的是&#xff0c; 更新语句涉及到【事务】&#xff0c;就必须保证事务的四大特性&#xff1a;ACID&…

Java-IO模型分析

BIO&#xff08;同步阻塞&#xff09; 利用网络连接传输数据为例&#xff1a; 服务端单线程 服务端只有一个主线程处理客户端的连接和读写处理&#xff0c;此时如果有第二个客户端欲连接并发送消息服务端是接收不到的。 因为读写和等待accept连接都是阻塞的。 sever端代码…

【TypeScript】TS类型守卫(六)

【TypeScript】TS类型守卫&#xff08;六&#xff09; 【TypeScript】TS类型守卫&#xff08;六&#xff09;一、什么是类型守卫二、in操作符三、typeof操作符四、instanceof操作符五、自定义类型谓词函数 一、什么是类型守卫 TypeScript类型守卫&#xff08;Type Guards&…

微信小程序调用map数据 并在wxml中对数组进行截取的操作

wxs文件的位置如图 实现数组截取 只保留五张图片 <wxs module"filter" src"./slicefunc.wxs"></wxs> <view class"wrap"><view class"search-box" bindtap"toSearch"><view class"v1"…

eclipse 导入项目js报错问题

eclipse 导入项目后会出现项目中的js文件报错&#xff08;红叉&#xff09;&#xff0c;如下图所示&#xff0c;有时候报错的文件很多&#xff0c;需要集中处理。 解决办法&#xff1a; 右键项目名称》Properties》MyEclipse》JavaScript》Include Path&#xff0c;在右侧选择“…

opencv图片灰度二值化

INCLUDEPATH D:\work\opencv_3.4.2_Qt\include LIBS D:\work\opencv_3.4.2_Qt\x86\bin\libopencv_*.dll #include <iostream> #include<opencv2/opencv.hpp> //引入头文件using namespace cv; //命名空间 using namespace std;//opencv这个机器视…

jupyter切换conda虚拟环境

环境安装 conda install nb_conda 进入你想使用的虚拟环境&#xff1a; conda activate your_env_name 在你想使用的conda虚拟环境中&#xff1a; conda install -y jupyter 在虚拟环境中安装jupyter&#xff1a; conda install -y jupyter 重启jupyter 此时我们已经把该安装…

【LeetCode每日一题】——575.分糖果

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 哈希表 二【题目难度】 简单 三【题目编号】 575.分糖果 四【题目描述】 Alice 有 n 枚糖&…

下载程序到西门子PLC

更多关于西门子S7-200PLC内容请查看&#xff1a;西门子200系列PLC学习课程大纲 下载西门子200PLC程序分以下两步&#xff1a; 一.编译程序 1. 如下图1-1所示&#xff0c;使用PPI电缆将PLC和电脑连接上&#xff0c;注意笔记本使用USB转PPI电缆&#xff0c;连接保证给PLC单独供…

postman官网下载安装登录测试详细教程

目录 一、介绍 二、官网下载 三、安装 四、注册登录postman账号&#xff08;不注册也可以&#xff09; postman注册登录和不注册登录的使用区别 五、关于汉化的说明 六、使用示范 一、介绍 简单来说&#xff1a;是一款前后端都用来测试接口的工具。 展开来说&#xff1a;…