【Linux】静态库的制作和使用详解

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++🔹Liunx
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、库的基础知识
  • 二、如何编写静态库
    • 1.原理简述
    • 2.实际操作
    • 3.使用makefile文件自动化构建
  • 四、静态库的使用

前言:

本篇博客讲解两个类型的库:动态库(.so) 和 静态库(.a).的制作。

一、库的基础知识

库的作用:提升开发效率。隐藏源代码

库的本质:将所有的[.o]结尾的可执行目标二进制文件打包形成一个文件夹。

二、如何编写静态库

1.原理简述

你编写了好几个文件,给别人使用,但是又不想让使用者看到内部源代码,此时有没有什么办法呢。

本质就是隐藏.c源文件。

  • 第一步:将所有.c的文件形成.o文件

  • 第二步:将所有的.o使用ar指令打包成一个库文件。

  • 具体流程如下图:

在这里插入图片描述

这样做的好出有:
(1)将所有的源文件打包好,防止使用者再拷贝时丢失原文件。提高了使用效率。
(2)使用者无法查看源码,提高了安全性

2.实际操作

分别创建了4个文件:mymath.h mymath.c myprint.h myprint.c.

  • 1.<mymath.h>:
#pragma once    
#include<stdio.h>    
    
extern int addToTarget(int start, int end);//声明函数
  • 2.mymath.c
  #include "mymath.h"                                             #             
                                                                                     
  //这段函数的作用是计算start-end之间的和
  int addToTarget(int start, int end)                               
  {                                                                
    int sum = 0;                                                   
    int i = start;                                                 
    for(i; i <= end; i++)
    {                                                                                                                                 
      sum += i;                                                    
    }                                                              
    return sum;                                                    
  }  
  • 3.myprint.h
#pragma once     
    
#include<stdio.h>    
#include<time.h>    
    
extern void Print(const char* str);  
  • 4.myprint.c
#include "myprint.h"                                                            
 
//这段函数功能是输出传入的字符串,后面加上时间戳                                                                    
void Print(const char* str)                                                          
{
  printf("%s[%d]\n",str,(int)(time(NULL)));
}       

有了上面四个文件后,还需要写一个main方法使用这些函数。

#include "myprint.h"    
#include "mymath.h"    
    
int main()    
{    
  Print("hello,world");                                                                                                               
  int res = addToTarget(1,100);    
    
  printf("res: %d\n",res);    
    
  return 0;    
}    

开始制作静态库:
第一步:将所有的.c文件–>.o文件
使用gcc的【-c】选项,代码如下:

gcc -o myprint.o -c myprint.c
gcc -o mymath.o -c mymath.c

注意:main函数不用参与,每个使用者都会有自己的main方法去调用库文件。

第二步:o文件打包成名字叫hello的静态库
知识补充:

【ar】指令:
ar -[选项] + lib+库文件名.a + 所有.o文件
选项这里只说r(replace替换),c(create创建)就可以了,就足以让我们创建静态库了.
注意: 格式一定是lib+库文件名.a。也就是说要形成的静态库的名字 前缀必须是lib,后缀必须是.a,中间可以随便起名字.

执行代码:

ar -rc libhello.a main.o myprint.o mymath.o

在这里插入图片描述

可以发现,此时目录下面就会存在刚打包好的库文件了,但是,还需要结合对应的头文件才能正确的使用库文件中的函数。往下学!

3.使用makefile文件自动化构建

理清楚一个文件形成静态库的过程后 总结来说: .c文件 —> .o文件 —>
打包形成静态库

既然是这么一套固定的流程,那么我们完全可以用Makefile来完成这些工作。需要注意的是搞清各个文件的依赖关系,然后再进行编写。

所以最后的Makefile编写如下:

libhello.a: mymath.o myprint.o                                                                                                        
  ar -rc libhello.a mymath.o myprint.o    
mymath.o : mymath.c    
  gcc -o mymath.o -c mymath.c    
myprint.o: myprint.c    
  gcc -o myprint.o -c myprint.c    
    
.PHONY:clean    
clean:    
  rm -rf *.o libhello.a    

在这里插入图片描述

这样还没有结束:还有对应的许多头文件呢。一般都是.h声明,然后从.o打包形成的库里面找。

  • 所以我们还需要做一件工作:将.h和.a文件规整到一起.在Makefile加入以内容:就是将头文件和库文件规整在一起,逻辑如下 在这里插入图片描述

  • 在这里插入图片描述

  • makefile代码如下

.PHONY:hello    
hello:    
  mkdir -p hello/lib    
  mkdir -p hello/include    
  cp -rf *.h hello/include    
  cp -rf *.a hello/lib  
  • 总结来说: .c文件 —> .o文件 —> 打包形成静态库–>最后将.h和.a文件规整到一起

这样就制作好了一个静态库!如何去使用呢?

四、静态库的使用

方法一:直接拷贝到系统路径

头文件gcc系统默认搜索路径是:/usr/include
库文件gcc系统默认搜索路径是:/lib64 或者 /usr/lib64

  • 可以将你编写的静态库拷贝进/usr/lib64。头文件拷贝进/usr/include ;但是这样做会污染原来别人已经写好的库。不建议使用

方法二:指定路径搜索

我们可以直接在编译的时候加上头文件和库文件的路径.
对于上面的代码我们执行:

gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello

就可以指定路径进行查找。

选项:-I(i的大写)表示头文件的搜索路径
-L表示库文件的搜索路径
-l(小写的L)表示在特定路径下,要使用哪一个库.

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Spring Boot】Spring原理:Bean的作用域和生命周期

目录 Spring原理一. 知识回顾1.1 回顾Spring IOC1.2 回顾Spring DI1.3 回顾如何获取对象 二. Bean的作用域三. Bean的生命周期 Spring原理 一. 知识回顾 在之前IOC/DI的学习中我们也用到了Bean对象&#xff0c;现在先来回顾一下IOC/DI的知识吧&#xff01; 首先Spring IOC&am…

权利之望账号注册教程 权力之望游戏客户端下载教程

权力之望&#xff0c;一款马上就要上线的新的MMORPG游戏&#xff0c;非常好玩大型多人在竞技的游戏&#xff0c;玩家在游戏中有着60多种不同的职业可以选择&#xff0c;而且整个游戏的画面非常精美&#xff0c;更有各种不同的武器装备可以选择&#xff0c;热血的战斗和各种大型…

c语言的简易教法—— 函数递归

文章目录 一、什么是递归&#xff1f;1.1递归的思想1.2递归的限制条件 二、递归案例2.1 案例1&#xff1a;求n的阶层2.1.1分析2.1.2 递归函数&#xff08;Fact&#xff09;的代码实现2.1.3 测试&#xff1a;main函数实现2.1.4 运行结果和画图推演2.1.5 扩展&#xff1a;迭代方法…

配置Java开发环境

Java是一种广泛使用的编程语言&#xff0c;特别是在企业应用和安卓开发中。本文将详细介绍如何在您的计算机上配置Java开发环境&#xff0c;包括安装JDK、配置环境变量以及选择和设置IDE。 一、安装Java Development Kit (JDK) JDK&#xff08;Java Development Kit&#xff0…

IDEA阿里云OSS实现文件上传·解决苍穹外卖图片回显

简单交代配置阿里云OSS的思路 1. 首先去阿里云开通一个OSS服务&#xff0c;配置好一个自己的Bucket 2. 在IDEA配置Bucket 3. 拷贝官网的OSS工具类代码 package com.sky.utils;import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSS…

Redis 配置与优化

一、关系型数据库与非关系型数据库 &#xff08;一&#xff09;关系型数据库 关系型数据库是结构化数据库&#xff0c;创建在关系型模型数据库&#xff0c;创建面向于记录。 常见的关系型数据库&#xff1a;Oracle、MySQL、SQL Server、Microsoft Access、DB2。 &#xf…

2024年浙江省高考分数一分一段数据可视化

下图根据 2024 年浙江高考一分一段表绘制&#xff0c;可以看到&#xff0c;竞争最激烈的分数区间在620分到480分之间。 不过&#xff0c;浙江是考两次取最大&#xff0c;不是很有代表性。看看湖北的数据&#xff0c;580分到400分的区段都很卷。另外&#xff0c;从这个图也可以…

【vue】下载 打印 pdf (问题总结)- 持续更新ing

这里是目录标题 一、pdf1.查看 下载一、pdf 1.查看 下载 样式 Code<template><div><el-table :data="pdfList" style="width: 100%" border ><el-table-columnprop="index"label="序号"width="80"ali…

告别低效地推!Xinstall助力,一键生成专属渠道二维码

在移动互联网时代&#xff0c;地推作为一种传统而有效的推广方式&#xff0c;依然被众多企业所青睐。然而&#xff0c;传统的地推方式往往伴随着繁琐的填码、人工登记以及难以追踪的下载来源等问题&#xff0c;极大地降低了推广效率。为了解决这些痛点&#xff0c;Xinstall应运…

5,智能合约(react+区块链实战)

5&#xff0c;智能合约&#xff08;react区块链实战&#xff09; 5-1 智能合约5-2 metamask安装及私有链搭建互相联动5-3 solidity数据类型-布尔-数字-地址&#xff08;owner区别&#xff09;5-4 solidity 数组和映射&#xff08;代币转账&#xff09;5-5 solidity结构体与枚举…

AI虚拟医生重塑医患关系

如今&#xff0c;越来越多的企业开始选择用AI虚拟数字人播报员替代真人出镜&#xff0c;这不仅有助于企业实现降本增效的目标&#xff0c;更能让广告传播趋向多样化和个性化。对于普通人而言&#xff0c;也摆脱了真人出镜的种种烦恼&#xff0c;让表达更加自由与便捷。AI虚拟数…

视频太大怎么压缩变小?这几种压缩方法值得收藏!

视频太大怎么压缩变小&#xff1f;在数字化浪潮汹涌的时代&#xff0c;处理大型视频文件已不再仅仅是存储空间的挑战&#xff0c;我们身处于数据洪流之中&#xff0c;数据的安全与隐私的保护已然成为了我们不得不面对的重大议题&#xff0c;特别是随着视频内容的井喷式增长及其…

怎么提高音频的播放速度?可以提高音频播放速度的四种方法推荐

怎么提高音频的播放速度&#xff1f;提高音频的播放速度是一种有效的策略&#xff0c;可以显著节省时间和提升信息获取的效率。随着信息量不断增加和学习需求的多样化&#xff0c;快速播放音频已成为许多人在日常生活和工作中的常见做法。这种方法不仅可以用于提高学习效率&…

医院人员管理系统03_下午:C3P0连接池,完成简单的增删改查

文章目录 什么是C3P0项目目录Students.javaC3P0Conn.javaStuDao.java套路代码 什么是C3P0 C3P0连接池要比jdbc更简单&#xff0c;dao层写方法就能看出来 项目目录 Students.java 没有变&#xff0c;直接是jdbc的实体类 跳转我的上一篇文章查看实体类代码 C3P0Conn.java 这…

Elasticsearch:Node.js ECS 日志记录 - Winston

这是继上一篇文章 “Elasticsearch&#xff1a;Node.js ECS 日志记录 - Pino” 的续篇。我们继续上一篇文章来讲述使用 Winston 包来针对 Node.js 应用生成 ECS 向匹配的日子。此 Node.js 软件包为 winston 记录器提供了格式化程序&#xff0c;与 Elastic Common Schema (ECS) …

一键掌握天气动态 - 基于Vue和高德API的实时天气查询

前言 本文将学习如何使用Vue.js快速搭建天气预报界面,了解如何调用高德地图API获取所需的天气数据,并掌握如何将两者有机结合,实现一个功能丰富、体验出色的天气预报应用 无论您是前端新手还是有一定经验,相信这篇教程都能为您带来收获。让我们一起开始这段精彩的Vue.js 高德…

音视频开发—FFmpeg 从MP4文件中抽取视频H264数据

文章目录 MP4文件存放H264数据方式MP4 文件结构概述H.264 数据在 MP4 中的存储1. ftyp 盒子2. moov 盒子3. mdat 盒子 H.264 数据在 stsd 盒子中的存储&#xff08;AVC1&#xff09;AVC1与Annex-B 格式&#xff08;裸 H.264 流&#xff09;的区别 从MP4文件中提取H264裸流步骤&…

zynq启动和程序固化流程

普通FPGA启动 FPGA的启动方式主要包含主动模式、被动模式和JTAG模式。 主动模式&#xff08;AS模式&#xff09; 当FPGA器件上电时&#xff0c;它作为控制器从配置器件EPCS中主动发出读取数据信号&#xff0c;并将EPCS的数据读入到自身中&#xff0c;实现对FPGA的编程。这种…

石油巨头受冲击!埃克森美孚、BP接连发出盈利预警

KlipC报道&#xff1a;近日&#xff0c;BP&#xff08;英国石油&#xff09;预计其第二季度将面临10亿至20亿美元的减值费用&#xff0c;并发出警告称其炼油利润率“大幅下降”&#xff0c;石油交易收益预计出现疲软。消息公布后&#xff0c;其股价下跌超4%。 由于中间馏分油利…

【三维重建】【深度学习】windows11下3DGS代码Pytorch实现

【三维重建】【深度学习】windows11下3DGS代码Pytorch实现 提示:最近开始在【三维重建】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【三维重建】【深度学习】windows11下3DGS代码Pytorch实现前言3DGS模型运行安装CUDA安装 Visual Studio C编…