【Linux】静态库和共享库一分钟快速上手
Linux
- 前言
- 对比
- 创建静态库
- 动态库
前言
程序库,对于程序原来说是非常重要的。但不少人对其不太了解,接下来一起学习其中的奥秘吧!
简单来说,程序库可以分为静态库和共享库。它们包含了数据和执行代码的文件。其不能单独执行,可以作为其他执行程序的一部分来完成某些功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码的重用,可以使得程序便于升级
对比
静态库是指在程序运行前就已经加入到执行代码中,成为执行程序的一部分。程序会把静态库加载到自己的内存当中,比如在Linux环境下,编译产生多个a.out,那么相当于每个a.out里面都会存有静态库的内存,从而大大削减了程序的运行时间,但是增加了空间大小,另外静态库更新比较麻烦,一般不做推荐
所以静态库适用于对空间要求比较低,对时间要求比较高的核心程序中
而相比共享库(动态库),是在执行程序启动时加载到执行程序中。它是这几个a.out用到库的时候一起去调用库文件,被多个执行程序共享使用。因此时间上效率就会下降,虽然节省了空间,但是耗费了时间。另外动态库是独立的,便于维护更新
所以动态库一般用在对时间要求低的,对空间要求高的设备上。
创建静态库
首先创建几个.cpp文件
创建两个cpp文件
[bsk@localhost linux_system]$ touch sum.cpp
[bsk@localhost linux_system]$ ls
sum.cpp
[bsk@localhost linux_system]$ vi sum.cpp
[bsk@localhost linux_system]$ ls
sum.cpp
bsk@localhost linux_system]$ touch div1.cpp
[bsk@localhost linux_system]$ cd d
bash: cd: d: No such file or directory
[bsk@localhost linux_system]$ vi div1.cpp
两个文件内容如下:
2 int sum(int a, int b) 3 {4 return a+b;5 }
2 int div1(int a, int b) 3 {4 return a/b;5 }
然后将.cpp文件生成 .o文件
[bsk@localhost linux_system]$ g++ -c sum.cpp -o sum.o
[bsk@localhost linux_system]$ ls
div1.cpp sum.cpp sum.o
[bsk@localhost linux_system]$ g++ -c div1.cpp -o div.o
再使用ar工具制作静态库
[bsk@localhost linux_system]$ ar rcs libmymath.a sum.o div.o
[bsk@localhost linux_system]$ ls
div1.cpp div.o libmymath.a sum.cpp sum.o
再编写主函数test.cpp
1 #include<iostream>2 using namespace std;3 int div1(int a,int b);4 int sum(int a, int b); 5 int main()6 {7 int a = 10;8 int b = 2;9 cout<<"a+b= " <<sum(a,b)<<endl;10 cout<<"a/b= " <<div1(a,b)<<endl;11 return 0;12 }
编译静态库到可执行文件中
[bsk@localhost linux_system]$ g++ libmymath.a test.cpp -o a.out
即可运行a.out
[bsk@localhost linux_system]$ ls
a.out div1.cpp div.o libmymath.a sum.cpp sum.o test.cpp
[bsk@localhost linux_system]$ ./a.out
a+b= 12
a/b= 5
其实上面这种方法有一点漏洞,就是头文件没有单独写出来
` #ifndef _MYMATH_H_ 2 #define _MAMATH_H_3 int div1(int a,int b);4 int sum(int a, int b);5 6 #endif
~ `
把头文件单独写出来,再在test.cpp中引用头文件即可。
可以再创建 lib 和inc 两个目录,然后把他们分别放进去
[bsk@localhost linux_system]$ mkdir inc
[bsk@localhost linux_system]$ mkdir lib
[bsk@localhost linux_system]$ mv *.h inc/
[bsk@localhost linux_system]$ mv *.a lib
即可运行
[bsk@localhost linux_system]$ g++ test.cpp ./lib/libmymath.a -o a.outy -I ./inc/
[bsk@localhost linux_system]$ ls
a.out a.outy div1.cpp div.o inc lib sum.cpp sum.o test.cpp -Wall
[bsk@localhost linux_system]$ ./a.outy
a+b= 12
a/b= 5
动态库
将.cpp文件生成 .o文件(要生成与位置无关的代码 -fPIC)
[bsk@localhost sourse]$ g++ -c sum.cpp -o sum.o -fPIC
[bsk@localhost sourse]$ g++ -c div1.cpp -o div1.o -fPIC
[bsk@localhost sourse]$ ls
div1.cpp div1.o sum.cpp sum.o
[bsk@localhost sourse]$
使用g++ -shared 制作动态库
g++ -shared -o lib库名.so sum.o div1.o
[bsk@localhost sourse]$ g++ -shared -o libmymath.so sum.o div1.o
[bsk@localhost sourse]$ ls
div1.cpp div1.o libmymath.so sum.cpp sum.o
[bsk@localhost sourse]$
编译可执行文件时,指定所使用的动态库
-l 指定库名 -L 指定库路径
[bsk@localhost dynamiclib]$ g++ test.cpp -o a.out -l mymath -L ./lib -I./inc
[bsk@localhost dynamiclib]$ ls
a.out inc lib sourse test.cpp
[bsk@localhost dynamiclib]$ ./a.out
./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
[bsk@localhost dynamiclib]$
如上所示竟然出错了,为什么呢?
首先先来了解一下链接器和动态链接器,
链接器: 工作于链接阶段,工作时需要 -l 和 -L
动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。
所以这个错误就是动态链接库因为找不到库文件,从而报错。
那我们应该如何去解决呢?
- 方法一:通过环境变量(临时生效)
方法也很简单,就是修改一下环境变量·
即LD_LIBRARY_PATH = 动态库路径。
[bsk@localhost dynamiclib]$ export LD_LIBRARY_PATH=./lib
[bsk@localhost dynamiclib]$ ./a.out
a+b= 12
a/b= 5
export的意思是让环境变量设定的值生效。
但是当我们关闭终端后,再重新打开一个终端(新进程),再运行的话,就会又报错,因为·我们设置的环境变量只能在当前进程中生效,所以要想它永久生效的话,就要修改配置文件了。
- 方法二:永久生效,写入终端配置文件(建议使用绝对路径)
[bsk@localhost ~]$ vi ~/.bashrc //修改配置文件
//进入后写入 export LD_LIBRARY_PATH=./lib
[bsk@localhost ~]$ . .bashrc
//重新·运行一下
即可永久生效
[bsk@localhost dynamiclib]$ ./a.out
a+b= 12
a/b= 5
但是还有一点缺点,就是当我们的/lib是相对命令,如果我们的文件相对于这个lib的路径发生改变了,所以就会又报错。所以一般我们就要使用绝对路径。
摒弃以上做法:
- 方法三:拷贝法(不推荐)
我们还可以把libmymath.os文件(自定义动态库)拷贝到系统根目录lib下(标准c库所在目录位置)
即可生效
但是此种方法也有一个缺点,就是它修改的系统级的目录,在系统中添加了自己的文件,不可靠,所以也不推荐使用
- 方法四:配置文件法
其实,我们还可以通过修改配置文件法:
首先: sudo vi /etc/ld.so.conf
然后写入 动态库的绝对路径,保存退出。
再重新运行,使配置文件生效
sudo ldconfig -v
此后再./a.out就可以永久成功啦
libmymath.so
[bsk@localhost lib]$ pwd
/home/bsk/test1/linux_system/dynamiclib/lib
[bsk@localhost lib]$ vi /etc/ld.so.conf[bsk@localhost lib]$ sudo vi /etc/ld.so.conf
[sudo] password for bsk:
[bsk@localhost lib]$ sudo ldconfig -v
.......[bsk@localhost dynamiclib]$ ./a.out
a+b= 12
a/b= 5相关文章:
【Linux】静态库和共享库一分钟快速上手
Linux 前言对比创建静态库动态库 前言 程序库,对于程序原来说是非常重要的。但不少人对其不太了解,接下来一起学习其中的奥秘吧! 简单来说,程序库可以分为静态库和共享库。它们包含了数据和执行代码的文件。其不能单独执行&#…...
C++继承总结(下)——菱形继承
一.什么是菱形继承 菱形继承是多继承的一种特殊情况,一个类有多个父类,这些父类又有相同的父类或者祖先类,那么该类就会有多份重复的成员,从而造成调用二义性和数据冗余。 class Person {public:Person(){cout << "P…...
CCF CCSP2023参赛记 + 算法题题解
大家好啊,时隔多年,作为大四老年人,再次来到这个地方记录算法竞赛相关,可能也是最后一次参加这种算法赛事了,我觉得还是很有纪念意义的。虽然我高中搞OI被强基背刺,以至于到了大学有点躲着竞赛,…...
buuctf_练[GYCTF2020]FlaskApp
[GYCTF2020]FlaskApp 文章目录 [GYCTF2020]FlaskApp常用绕过方法掌握知识解题思路解题一 -- 计算pin码解题二 -- 拼接绕过 执行命令 关键paylaod 常用绕过方法 ssti详解与例题以及绕过payload大全_ssti绕过空格_HoAd’s blog的博客-CSDN博客 CTF 对SSTI的一些总结 - FreeBuf网…...
针对element-plus,跳转jump(快速翻页)
待补充 const goToPage () > {const inputElement document.querySelector(.el-pagination .el-input__inner);console.log(inputElement, inputElement); } 打印之后可以看到分页跳转的数字输入框,是有进行处理的,max"102",是我自己的…...
【软件安装】Windows系统中使用miniserve搭建一个文件服务器
这篇文章,主要介绍如何在Windows系统中使用miniserve搭建一个文件服务器。 目录 一、搭建文件服务器 1.1、下载miniserve 1.2、启动miniserve服务 1.3、指定根目录 1.4、开启访问日志 1.5、指定启动端口 1.6、设置用户认证 1.7、设置界面主题 (…...
iOS .a类型静态库使用终端进行拆解和合并生成
项目中会用到许多第三方的.a类型的静态库,有时候会有一些静态库回包含相同文件而产生冲突,我们就需要对这个库进行去重的一个操作。一般有哪些文件冲突了,xcode报错都会有详细的提示。我们可以将这两个库合并,也可以其中一方中的文…...
react-组件间的通讯
一、父传子 父组件在使用子组件时,提供要传递的数据子组件通过props接收数据 class Parent extends React.Component {render() {return (<div><div>我是父组件</div><Child name"张" age{16} /></div>)} }const Child …...
【广州华锐互动】VR公司工厂消防逃生演练带来沉浸式的互动体验
在工业生产过程中,安全问题始终是我们不能忽视的重要环节。特别是火灾事故,不仅会造成重大的经济损失,更会威胁到员工的生命安全。传统的消防安全训练方法,如讲座、实地演练等,虽然具有一定的效果,但是无法…...
可观察性支柱:探索日志、指标和跟踪
通过检查系统输出来测量系统内部状态的能力称为可观察性。当可以仅使用输出信息(即传感器数据)来估计当前状态时,系统就变得“可观察”。您可以使用来自 Observability 的数据来识别和解决问题、优化性能并提高安全性。 在接下来的几节中&am…...
nginx浏览器缓存和上流缓存expires指令_nginx配置HTTPS
1.nginx控制浏览器缓存是针对于静态资源[js,css,图片等] 1.1 expires指令 location /static {alias/home/imooc;#设置浏览器缓存10s过期expires 10s;#设置浏览器缓存时间晚上22:30分过期expires @22h30m;#设置浏览器缓存1小时候过期expires -1h;#设置浏览器不缓存expires …...
硬件安全与机器学习的结合
文章目录 1. A HT Detection and Diagnosis Method for Gate-level Netlists based on Machine Learning摘要Introduction 2. 基于多维结构特征的硬件木马检测技术摘要Instruction 3. A Hardware Trojan Detection and Diagnosis Method for Gate-Level Netlists Based on Diff…...
腾讯云国际-如何使用对象存储COS在 CKafka 控制台创建数据异步拉取任务?腾讯云代充
操作场景 Datahub 支持接入各种数据源产生的不同类型的数据,统一管理,再分发给下游的离线/在线处理平台,构建清晰的数据通道。 本文以 COS 数据为例介绍如何在 CKafka 控制台创建数据异步拉取任务,并对任务进行修改配置…...
内存马概念
内存马概念 文章目录 内存马概念木马演变内存使用条件内存缺点JAVA Web三大组件Listener:监听器servelet请求流程内存马分类内存演示内存马植入方式案例shiro反序列化漏洞植入内存马 木马演变 内存使用条件 1. 禁止外联 2. 文件监控、查杀 3. spring Boot,不支持js…...
交换机基础(四):MSTP负载均衡配置案例
如图所示是某个企业内部核心网络的结构图,目前企业中有20个VLAN, 编号为VLAN1~VLAN20, 为了确保内部网络的可靠性,使用 了冗余链路和MSTP 协议。为了能更好地利用网络资源和带宽,现管理员希望通过配置MSTP 的负载均衡实现网络带宽…...
C# OpenCvSharp Yolov8 Face Landmarks 人脸特征检测
效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_Yolov8_Demo {public partial class frmMain…...
计算机网络之数据链路层(全)
[复习提示] 王道:本章是历年考试中考查的重点。要求在了解数据链路层基本概念和功能的基础上,重点掌握滑动窗口机制、三种可靠传输协议、各种MAC协议、HDLC协议和PPP协议,特别是CSMA/CD协议和以太网帧格式,以及局域网的争用期和最…...
前端TypeScript学习-交叉类型与泛型
交叉类型和泛型是TypeScript中的两个重要概念。 交叉类型(&)可以用来组合多个接口,形成一个新接口。它类似于接口继承(extends),但有一些区别。交叉类型不会产生类型继承层次结构,而是将多…...
科聪协作(复合)移动机器人整体解决方案
协作(复合)移动机器人(AGV/AMR)相较传统工业机器人具有更加安全和简单的工作优势,具备较强的发展潜力。协作(复合)移动机器人安全性和操作的简洁性、灵活性不断提高,优势得到了充分发挥,在越来越…...
RTE(Runtime Environment)
RTE(Runtime Environment)是一个运行时环境,在这个环境里,你可以实现的功能是: 作为一个缓冲buffer给应用层和BSW层的接口(例如COM)用来存储数据,也就是说定义一个全局变量供上层和下…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
DAY 45 超大力王爱学Python
来自超大力王的友情提示:在用tensordoard的时候一定一定要用绝对位置,例如:tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾: tensorboard的发展历史和原理tens…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
