Linux C/C++编程之静态库
【图书推荐】《Linux C与C++一线开发实践(第2版)》_linux c与c++一线开发实践pdf-CSDN博客
《Linux C与C++一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com)
【图书介绍】】几本Linux系统管理与开发图书_linux应用开发书籍-CSDN博客
10.3.1 静态库的基本概念
静态库文件的后缀为.a,在Linux下一般命名为libxxx.a。当有程序使用某个静态库时,在链接步骤中,链接器将从静态库文件中取得的代码复制到生成的可执行文件中,即整个库中的所有函数都被链接到可执行文件中。因此使用静态库的可执行文件通常较大。但使用静态库的优点也非常明显,即可执行程序最终运行时不需要和该库有关的文件的支持,因为所有使用的函数都已经被编译进去了,可执行文件可以直接运行。当然,有时候这也是一个缺点,比如静态库里的内容改变了,那么程序(调用者)必须重新编译。
10.3.2 静态库的创建和使用
通常使用ar命令来创建静态库。通过ar命令其实就是把一些目标文件(.o)组合在一起,成为一个单独的静态库。Linux上创建静态库的步骤如下:
(1)编辑源文件(比如.c或.cpp文件)。
(2)通过gcc -c xxx.c或g++ -c xxx.cpp生成目标文件(即.o文件)。
(3)用ar归档目标文件,生成静态库。
(4)配合静态库写一个头文件,文件里的内容就是提供给外面使用的函数、变量或类的声明。
要学会创建静态库,主要是学会ar命令的使用。ar命令不但可以创建静态库,还可以修改或提取已有静态库中的信息。它的常见用法如下:
ar [option] libxxx.a xx1.o xx2.o xx3.o ...
其中,option是ar命令的选项;libxxx.a是生成的静态库文件的名字,xxx通常是我们自己设定的名字,lib是一种习惯,静态库通常以lib开头;后面的xx1.o、xx2.o、xx3.o是要归档进静态库中的目标代码文件,可以有多个,所以后面用省略号。
常用选项如下:
(1)选项c:用来创建一个库。无论库是否存在,都将创建。
(2)选项s:创建目标文件索引,这在创建较大的库时能加快时间。如果不需要创建索引,可改成大写S参数;如果.a文件缺少索引,还可以使用ranlib命令添加。
(3)选项r:在库中插入模块,若插入的模块名已经在库中存在,则将替换同名的模块。如果若干模块中有一个模块在库中不存在,ar就会显示一个错误消息,并不会替换其他同名模块。默认情况下,新的成员增加在库的结尾处,可以使用其他任意选项来改变增加的位置。
(4)选项t:显示库文件中有哪些目标文件。注意,只显示名称。
(5)选项tv:显示库文件中有哪些目标文件。显示的信息包括文件名、时间、大小等。
(6)选项s:显示静态库文件中的索引表。
要使用静态库很简单,下面我们来看一个例子,生成一个静态库并使用它。
【例10.1】创建并使用静态库(g++版)
(1)打开Visual Studio Code,新建一个源文件test.cpp,内容如下:
#include <stdio.h>#include <iostream>using namespace std;void f(int age){cout << "your age is " << age << endl;printf("age:%d\n",age);}
代码很简单。这个源码文件主要作为静态库。我们首先将test.cpp文件上传到Linux,在命令行下输入以下命令:
# g++ -c test.cpp
此时会在test.cpp同目录下生成test.o目标文件。再输入以下命令来生成静态库:
# ar rcs libtest.a test.o
其中,ar是静态函数库创建的命令,c是create(创建)的意思,rs前面都有解释。
此时会在同目录下生成libtest.a静态库文件。注意,所要生成的.a文件的名字前3位最好是lib,否则在链接的时候,就可能找不到这个库。
(2)现在静态库生成了,我们另外编写一个源文件来使用该库中的函数f。打开Visual Studio Code,新建一个文件main.cpp,并输入如下代码:
extern void f(int age); // 声明要使用的函数#include <iostream>using namespace std;int main(int argc, char *argv[]){f(66);cout << "HI" << endl;return 0;}
代码很简单。首先声明一下f,然后就可以在main函数中使用了。保存文件后将其上传到Linux,注意要和libtest.a放在同一个目录,然后在命令行进行编译并运行:
# g++ -o main main.cpp -L. -ltest# ./mainyour age is 66age:66HI
编译运行成功了。其中,-L用来告诉g++去哪里找库文件,它后面加了一个点(.),表示在当前目录下去找库文件;-l用来指定具体的库,其中的lib和.a不用显式写出,g++或gcc会自动去寻找libtest.a,这也是我们前面生成静态库的时候,静态库的文件名要用lib前缀的原因。默认情况下,g++或gcc首先搜索动态库(.so)文件,找不到后再去寻找静态库(.a)文件。当前目录没有动态库文件,因此可以找到静态库文件。
gcc和g++使用静态库的过程类似,下面列举一个gcc版本的例子。
【例10.2】创建并使用静态库(gcc版)
(1)打开Visual Studio Code,新建一个源文件test.cpp,内容如下:
#include <stdio.h>void f(int age){printf("age:%d\n",age);}
这个源码文件主要作为静态库。我们首先将test.c文件上传到Linux,在命令行下输入如下命令:
# gcc -c test.cpp
此时会在test.cpp同目录下生成test.o目标文件。再输入以下命令来生成静态库:
# ar rcs libtest.a test.o
此时会在同目录下生成libtest.a静态库文件。
(2)现在静态库生成了,我们另外编写一个源文件来使用该库中的函数f。打开Visual Studio Code,新建一个文件main.cpp,并输入如下代码:
extern void f(int age); // 声明要使用的函数int main(int argc, char *argv[]){f(66);return 0;}
代码很简单,首先声明一下f,然后就可以在main函数中使用了。保存代码后将其上传到Linux,注意要和libtest.a放在同一个目录,然后在命令行进行编译并运行:
# gcc -o main main.cpp -L. -ltest# ./mainage:66
编译运行成功了。其中,-L用来告诉gcc去哪里找库文件,它后面加了一个点(.),表示在当前目录下去找库文件;-l用来指定具体的库,其中的lib和.a不用显式写出,g++或gcc会自动去寻找libtest.a。默认情况下,g++或gcc首先搜索动态库(.so)文件,找不到后再去寻找静态库(.a)文件。当前目录没有动态库文件,因此可以找到静态库文件。

相关文章:
Linux C/C++编程之静态库
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com…...
strlen函数用法,模拟实现
一、strlen 函数用法 用来求字符串长度,从我们给的地址开始,往后数,直到遇到 \0 停止,返回数的个数,不包括 \0 返回值类型是无符号整形 char arr[ ]"bvcxz"; printf("%u ",strlen(arr)); …...
云原生后端:解锁高效可扩展应用的魔法世界
目录 一、云原生后端的崛起:时代的必然选择 二、云原生后端的基石:容器化与 Docker (一)容器化的概念与优势 (二)Docker:容器化的明星工具 三、微服务架构:云原生后端的灵魂 &…...
大数据新视界 -- Hive 数据湖架构中的角色与应用(上)(25 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
React高阶面试题目(六)
React的formik库 定义: Formik是一个用于在React应用程序中构建和处理表单数据的流行开源库。它提供了许多实用的组件和函数,使在React应用程序中处理表单数据变得更加轻松。 优点: 自动处理表单状态管理,无需手动编写大量的状态…...
容器运行应用及Docker命令
文章目录 一、使用容器运行Nginx应用1_使用docker run命令运行Nginx应用1 观察下载容器镜像过程2 观察容器运行情况 2_访问容器中运行的Nginx服务1 确认容器IP地址2 容器网络说明3 使用curl命令访问 二、Docker命令1_Docker命令获取帮助方法2_Docker官网提供的命令说明3_docker…...
【Go 基础】channel
Go 基础 channel 什么是channel,为什么它可以做到线程安全 Go 的设计思想就是:不要通过共享内存来通信,而是通过通信来共享内存。 前者就是传统的加锁,后者就是 channel。也即,channel 的主要目的就是在多任务间传递…...
windows10更新后system磁盘占用100%
windows10更新后system磁盘占用100% 现象: 解决办法: 打开服务禁用:Connected User Experiences and Telemetry 我现在已经把该服务禁用了,已经没有再出现不停写入的情况。 服务描述:“已连接的用户体验和遥测服务所…...
无人设备遥控器之防水性能篇
无人设备遥控器的防水性能是评估其耐用性和适应不同环境能力的重要指标。随着无人设备技术的不断发展,越来越多的遥控器在设计时融入了防水元素,以满足用户在不同天气条件下的使用需求。 一、防水等级与标准 无人设备遥控器的防水性能通常通过防水等级来…...
基于Matlab BP神经网络的非线性系统辨识与控制研究
随着现代工业和科学技术的不断发展,非线性系统的建模和控制成为了自动化领域中的重要研究课题。传统的系统辨识方法往往难以应对系统的复杂性和非线性特性,而人工神经网络(ANN)凭借其强大的逼近能力和自适应性,已广泛应…...
3D基因组工具(HiC可视化)trackc--bioinfomatics tools 35
01 3D genome data analysis guides 茶树三维基因组-文献精读19 https://trackc.readthedocs.io/en/latest/install.html #官网 https://github.com/seqyuan/trackc #官网https://trackc.readthedocs.io/en/latest/analysis_guide/index.html #HiC可视化案例 …...
【大模型微调】图片转pdf
有时候图片需要转成pdf https://www.bilibili.com/opus/982151156821131282 https://help.pdf24.org/ https://www.bilibili.com/video/BV163v2eyEWo/?vd_source=8318f88fcdf4948d2b21fae7c9cf3184 2024最新!小白如何安装破解版的 Acrobat https://www.32r.com/zt/dgyjzzrj/ …...
Linux-Ubuntu16.04摄像头 客户端抓取帧并保存为PNG
1.0:client.c抓取帧并保存为PNG #include <stdio.h> // 标准输入输出库 #include <stdlib.h> // 标准库,包含内存分配等函数 #include <string.h> // 字符串操作库 #include <linux/videodev2.h> // V4L2 视频设备…...
手机ip地址取决于什么?可以随便改吗
手机IP地址是指手机在连接到互联网时所获得的唯一网络地址,这个地址由一串数字组成,用于在网络中标识和定位设备。每个设备在连接到网络时都会被分配一个IP地址,它可以帮助数据包在网络中准确地找到目标设备。那么,手机IP地址究竟…...
计算机网络:TCP/IP协议的五大重要特性介绍
目录 一、逻辑编址 二、路由选择 三、名称解析 四、错误控制和流量控制 五、多应用支持 今天给大家聊聊TCP/IP协议中五大重要特性相关的知识,希望对大家深入了解该协议提供一些帮助! 一、逻辑编址 首先要了解什么是物理地址、逻辑地址。 ●...
Java与AWS S3的文件操作
从零开始:Java与AWS S3的文件操作 一、什么是 AWS S3?AWS S3 的特点AWS S3 的应用场景 二、Java整合S3方法使用 MinIO 客户端操作 S3使用 AWS SDK 操作 S3 (推荐使用) 三、总结 一、什么是 AWS S3? Amazon Simple Sto…...
详解 YOLOv5 模型运行参数含义以及设置及在 PyCharm 中的配置方法
详解 YOLOv5 模型运行参数含义以及设置及在 PyCharm 中的配置方法 这段代码中使用的命令行参数允许用户在运行 YOLOv5 模型时自定义多种行为和设置。以下是各个参数的详细说明和使用示例,以及如何在 PyCharm 中设置这些参数以确保正确运行带有参数的脚本。 命令行…...
Vue根据Div内容的高度给其Div设置style height
在 Vue.js 中,你可以使用 JavaScript 来动态地根据 div 的内容高度来设置其 style 的 height 属性。这通常是在组件挂载或更新时完成的,因为这时你已经有了实际的 DOM 元素可以操作。 以下是一个简单的例子,展示了如何实现这一点:…...
驱动篇的开端
准备 在做之后的动作前,因为win7及其以上的版本默认是不支持DbgPrint(大家暂时理解为内核版的printf)的打印,所以,为了方便我们的调试,我们先要修改一下注册表 创建一个reg文件然后运行 Windows Registr…...
OpenSSL 自建CA 以及颁发证书(网站部署https双向认证)
前言 1、前面写过一篇 阿里云免费ssl证书申请与部署,大家可以去看下 一、openssl 安装说明 1、这部分就不再说了,我使用centos7.9,是自带 openssl的,window的话,要去下载安装 二、CA机构 CA机构,全称为…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
