第三方库介绍——zlib库

article/2025/10/9 12:37:04

文章目录

  • zlib
    • 1. zlib库介绍
    • 2. zlib库的应用
    • 3. 下载地址
    • 4. 函数使用教程
      • 4.1 compress 与 uncompress
      • 4.3 使用过程解析
      • 4.2 infate、deflate、z_stream
    • 5. 交叉编译zlib库

zlib

1. zlib库介绍

  • zlib是一套通用的解压缩开源库,提供了内存(in-memory)压缩和解压函数,能检测解压出来的数据完整性,zlib 也支持读写 gzip (.gz) 格式的文件,可以阅读:zlib库介绍三:gzip(.gz格式)文件读写
  • 默认且目前仅使用deflate算法压缩data部分;deflate是一种压缩算法,是huffman编码的一种加强。

2. zlib库的应用

数以万计的应用程序直接或间接依靠zlib压缩函式库,包括:

  • FFmpeg:以zlib读写Matroska等以DEFLATE算法压缩的多媒体串流格式。
  • OpenSSH、OpenSSL:以zlib达到最佳化加密网络传输。
  • Linux核心:使用zlib以实作网络协定的压缩、档案系统的压缩以及开机时解压缩自身的核心。
  • libpng,用于PNG图形格式的一个实现,对bitmap数据规定了DEFLATE作为流压缩方法。
  • 略、、、、

参考博文:zlib库介绍一:zlib简介

3. 下载地址

  • zlib官网下载

  • 所有版本的下载地址

4. 函数使用教程

zlib 在 examples 路径下提供了许多使用zlib的例子:

在这里插入图片描述
在README.examples 有介绍各个example的作用。

4.1 compress 与 uncompress

compress和uncompress是zlib最基本的两个函数了。他们分别用于压缩和解压数据。 原型如下:

int compress(unsigned char* dest,unsigned long*destLen, const unsigned char* source, unsigned long sourceLen);int compress2(unsigned char* dest, unsigned long*destLen, const unsigned char* source,unsigned long sourceLen, int level);

参数:

  • dest:压缩之后的数据缓冲区。
  • desLen:压缩之后的数据缓冲区长度。
  • source:原始数据缓冲区(压缩之前的数据内容)。
  • sourceLen:原始数据长度。
  • level:level:压缩比例,压缩级别取值:0 - 9。0压缩速度最快,9压缩速度最慢,压缩率最大。0表示不进行压缩。【compress2才有】

返回值:

  • Z_OK:成功。
  • Z_MEM_ERROR:没有足够的内存。
  • Z_BUF_ERROR:输出的缓冲区没有足够的空间。
  • Z_STREAM_ERROR:level参数设置不正确。【compress2才有】
int uncompress(unsigned char* dest, unsigned long* destLen,unsigned char* source, unsigned long sourceLen);int uncompress2(unsigned char* dest,unsigned long* destLen,unsigned char* source, unsigned long* sourceLen);

参数:

  • dest:解缩之后的数据缓冲区

  • desLen:解缩之后的数据缓冲区长度

  • source:要解压的数据缓冲区

  • sourceLen:要解压的数据长度

返回值:

  • Z_OK:成功。

  • Z_MEM_ERROR:没有足够的内存。

  • Z_BUF_ERROR:输出的缓冲区没有足够的空间。

  • Z_DATA_ERROR:输入的原始数据(source)被损坏了,或不完整。

uncompress2函数相比于uncompress函数,原始数据长度采用指针进行表示。

4.3 使用过程解析

  1. 压缩、解压过程 方案一

压缩:deflateInit() ->deflate() ->deflateEnd();

解压:inflateInit() -> inflate() -> inflateEnd();

  1. 压缩、解压过程 方案二

压缩:deflateInit2() ->deflate() ->deflateEnd();

解压:inflateInit2() -> inflate() -> inflateEnd();

ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen));
ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,const Bytef *source, uLong sourceLen));

参数类型

  • Bytef表示字节流,它与字符串有所不同,字节流没有结束符,因而需要配备长度信息,处理字符串的时候需要把结束符也当成一个普通的字节。
  • uLongf则用于指明长度信息了, 其实相当于unsigned long。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>#include <zlib.h>int main(int argc, char *argv[])
{ char inbuf[] = "Hello, This is a demo for compress and uncompress interface!\n""Written by windeal.li\n""email: 2378264731@qq.com\n";uLong inlen = sizeof(inbuf);char *outbuf = NULL;uLong outlen;outlen = compressBound(inlen);printf("in_len: %ld\n", inlen);printf("out_len: %ld\n", outlen);if ((outbuf = (char *)malloc(sizeof(char) * outlen)) == NULL){fprintf(stderr, "Failed to malloc memory for outbuf!\n");return -1;}/* compress */if (compress(outbuf, &outlen, inbuf, inlen) != Z_OK) {fprintf(stderr, "Compress failed!\n");return -1;}printf("Compress Sucess!\n");printf("\routlen:%ld, outbuf:%s\n", outlen, outbuf);memset(inbuf, 0, sizeof(inbuf));/* Uncompress */if (uncompress(inbuf, &inlen, outbuf, outlen) != Z_OK){fprintf(stderr, "Uncompress failed!\n");return -1;}printf("Uncompress Success!\n");printf("\rinlen:%ld, inbuf:%s\n", inlen, inbuf);/* free memory */if (outbuf != NULL){free(outbuf);outbuf = NULL;}return 0;
}

4.2 infate、deflate、z_stream

这里infate 和defate 其实是指两组函数

  • deflateInit() + deflate() + deflateEnd()用于完成流的压缩
  • inflateInit() + inflate() + inflateEnd()用于完成解压缩功能
int deflateInit (z_streamp strm, int level);  //初始化压缩状态,关联相关的z_stream数据结构和压缩比例
int deflate (z_streamp strm, int flush);   //压缩数据,  flush表示以何种方式将压缩的数据写到缓冲区中。
int deflateEnd (z_streamp strm);    //压缩结束int inflateInit (z_streamp strm);        
int inflate (z_streamp strm, int flush);
int inflateEnd (z_streamp strm); 

z_stream是上面两组函数中用到的,用来表示流的数据结构。

typedef struct z_stream_s {z_const Bytef *next_in;   // 将要压缩数据的首地址uInt     avail_in;  // 将要压缩数据的长度uLong    total_in;  // 将要压缩数据缓冲区的长度Bytef    *next_out;  // 压缩后数据保存位置。uInt     avail_out; // 压缩后数据的长度uLong    total_out; // 压缩后数据缓冲区的大小z_const char *msg; // 存放最近的错误信息,NULL表示没有错误struct internal_state FAR *state; /* not visible by applications */alloc_func zalloc;  /* used to allocate the internal state */free_func  zfree;   /* used to free the internal state */voidpf     opaque;  /* private data object passed to zalloc and zfree */int     data_type;   // 表示数据类型,文本或者二进制uLong   adler;      /* adler32 value of the uncompressed data */uLong   reserved;   /* reserved for future use */
} z_stream;    

关于这两组函数的具体使用, zlib-1.2.11/examples/zpipe.c或zlib-1.2.11/test/example.c,可以直接参考。

参考博文:

zlib库 安装与使用

zlib库使用简单讲解

5. 交叉编译zlib库

linux主机:ubuntu-18.04

交叉编译器:arm-buildroot-linux-gnueabihf

开发板kernel:Linux 5.4.0-150-generic x86_64

开发板:100ASK_STM32MP157_PRO开发板

zlib版本:zlib-1.2.11.tar.gz


下载

zlib-1.2.11.tar.gz

解压

tar xvf zlib-1.2.11.tar.gz

引入交叉编译器【zlib的configure不支持设置–host项】

export CC=/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/arm-buildroot-linux-gnueabihf-gcc

除了上面的引入交叉编译器,也可以手动更改Makefile,vim命令打开Makefile文件,将其中的CC、AR、RANLIB等都修改为arm-linux交叉编译器的相关参数

配置configure,指定安装后的文件在install文件夹里面

./configure --prefix=$PWD/install

在这里插入图片描述

编译

make

在这里插入图片描述

安装

sudo make install

在这里插入图片描述
由于前面运行configure文件的时候指定了安装的路径

cd install/lib

lib库里面包含静态库和动态库,注意软连接

book@100ask:~/Desktop/zlib/zlib-1.2.11/install/lib$ ls -lath
total 248K
drwxrwxr-x 5 book book 4.0K Jun 18 21:46 ..
drwxrwxr-x 2 book book 4.0K Jun 18 21:46 pkgconfig
drwxrwxr-x 3 book book 4.0K Jun 18 21:46 .
lrwxrwxrwx 1 book book   14 Jun 18 21:46 libz.so -> libz.so.1.2.11
lrwxrwxrwx 1 book book   14 Jun 18 21:46 libz.so.1 -> libz.so.1.2.11
-rwxr-xr-x 1 book book 120K Jun 18 21:46 libz.so.1.2.11
-rw-r--r-- 1 book book 113K Jun 18 21:46 libz.a

检查编译结果

file libz.so.1.2.11 

在这里插入图片描述

使用zlib的接口,只需在 链接命令后加-lz /usr/llocal/lib/libz.a 即可。

gcc -o zpipe.o -c zpipe.c
gcc -o zpipe zpipe.o -lz /usr/local/lib/libz.a 

参考博文:zlib开发笔记(三):zlib库介绍、在ubuntu上进行arm平台交叉编译


http://chatgpt.dhexx.cn/article/PITNYyUF.shtml

相关文章

Zlib的安装与测试

官方网址:http://www.zlib.net/ 进入官网看到,如图所示,最新版本为zlib 1.2.11 然后你用wget http://www.zlib.net/zlib 1.2.11或者wget http://www.zlib.net/zlib-1.2.11下载,那你永远下载不了. 嘿嘿,正确的下载方式是wget http://www.zlib.net/zlib-1.2.11.tar.gz 进入…

Java多线程(详细了解java多线程机制)

每天进步一点点 一、程序、进程、线程1.1 什么是程序1.2 什么是进程1.3 什么是线程1.4 进程和线程的区别 二、创建线程的三种方式2.1 继承Thread类重写run()方法具体实现获取线程ID和名称修改线程名称 2.2 实现Runnable接口实现run()方法具体实现使用匿名内部类 2.3 实现Callab…

JAVA多线程和并发编程(三)- JAVA多线程信息共享

我们通常希望多个线程之间有信息的通信&#xff0c;而不是每个线程各自run方法执行完就结束了。那么多个线程间如何通信呢&#xff1f; Java中多线程通常通过共享变量进行信息共享。 1&#xff09;使用static变量共享信息&#xff0c;该方法适用于通过继承Thread类创建线程的方…

Java多线程的知识点

&#x1f331;&#x1f331;友友们大家好 我是你们的小王同学啊 今天给大家带来的是 java多线程的知识点 希望大家能支持小王 喜欢就给个三连吧 你们的三连是我制作的动力&#xff01;&#x1f497;&#x1f497; 小王的gitee&#xff1a;小王同学&#x1f370; 小王的github&a…

java线程调度

线程调度分为两种形式 1 分时调度模型: 所有线程轮流获得CPU使用权&#xff0c;平均分配每一个线程的CPU时间片 2 抢占式调度模型: 优先让优先级更高的线程使用CPU&#xff0c;如果线程优先级相同 那机会随机分配优先级 给优先级高的线程更多一些的时间片 而java的分配模式 是…

java多线程(详)

目录 一,什么叫线程&#xff1f; 那我们要先了解什么叫进程&#xff0c;线程依赖于进程而存在的。 二.多线程的创建 方式一&#xff1a;继承Thread类 方式二&#xff1a;实现Runnable接口 方式三&#xff1a;JDK 5.0新增&#xff1a;实现Callable接口 三种方式的比…

Java线程、Java多线程详细介绍

目录 一、进程和线程的区别 1.1 进程 1.2 线程 二、并发和并行 2.1 并行 2.2 并发 2.3 监控线程的执行情况 三、创建方式 3.1 继承Thread类 思考&#xff1a;为什么不直接通过对象调用start&#xff08;&#xff09;方法&#xff1f; 3.2 实现Runnable接口 …

【java】java多线程及线程池详解

目录 前言线程是什么&#xff1f;多线程是什么&#xff1f;多线程的作用和好处以及缺点守护线程和用户线程并发和并行的区别 一.线程的状态和常用方法1.线程各种状态转化图2.线程相关常用方法有① wait()② sleep(long timeout)③ join()④ yield()⑤ notify()和notifyAll() 3.…

Java线程池(超详细)

文章目录 1. 线程池概念2. JUC线程池架构3. Executors创建线程的4种方法4. 线程池的标准创建方式5. 向线程池提交任务的两种方式6. 线程池的任务调度流程7. ThreadFactory&#xff08;线程工厂&#xff09;8. 任务阻塞队列9. 调度器的钩子方法10. 线程池的拒绝策略11. 线程池的…

Java多线程超详解

引言 随着计算机的配置越来越高&#xff0c;我们需要将进程进一步优化&#xff0c;细分为线程&#xff0c;充分提高图形化界面的多线程的开发。这就要求对线程的掌握很彻底。 那么话不多说&#xff0c;今天本帅将记录自己线程的学习。 程序&#xff0c;进程&#xff0c;线程的…

java多线程(超详细)

1 - 线程 1.1 - 进程 进程就是正在运行中的程序&#xff08;进程是驻留在内存中的&#xff09; 是系统执行资源分配和调度的独立单位 每一进程都有属于自己的存储空间和系统资源 注意&#xff1a;进程A和进程B的内存独立不共享。 1.2 - 线程 线程就是进程中的单个顺序控制…

JAVA线程

一、线程相关概念 &#xff08;一&#xff09;程序、进程和线程的区别 程序 程序是含有指令和数据的文件&#xff0c;被存储在磁盘或其他的数据存储设备中&#xff0c;也就是说程序是静态的代码。 进程 进程是程序的一次执行过程&#xff0c;是系统运行的基本单位&#xf…

Java 线程 基础知识总结

线程基础 很不严谨的说&#xff0c;线程是什么&#xff1f;线程就是为了让很多个东西并发执行&#xff0c;大大的提高程序执行的效率啊 三个非常重要的概念&#xff1a; 程序&#xff1a;一组写好了的静态代码块&#xff08;就我们写的那些代码玩意&#xff09;进程&#xf…

Java多线程(超详解)

目录 1. 线程简介 1.1 程序 1.2 进程 1.3 线程 1.4 多线程 1.5 普通方法调用和多线程 2. 线程创建 2.1 继承Thread类 2.2 实现Runnable接口 2.3 实现Callable接口&#xff08;了解&#xff09; 2.4 网图下载 2.4.1 通过继承Thread类实现网图下载 2.4.2 通…

java 线程详解

一、线程的基本概念 一个程序最少需要一个进程&#xff0c;而一个进程最少需要一个线程。关系是线程–>进程–>程序的大致组成结构。所以线程是程序执行流的最小单位&#xff0c;而进程是系统进行资源分配和调度的一个独立单位。 一个线程就是在进程中的一个单一的顺序…

JAVA多线程详解(超详细)

目录 一、线程简介1、进程、线程2、并发、并行、串行3、进程的三态 二、线程实现1、继承Thread类2、实现Runnable接口3、实现Callable接口&#xff08;不常用&#xff09; 三、线程常用方法1、线程的状态2、线程常用方法 四、多线程1、守护&#xff08;Deamon&#xff09;线程2…

Java多线程(超详细!)

1、什么是进程&#xff1f;什么是线程&#xff1f; 进程是:一个应用程序&#xff08;1个进程是一个软件&#xff09;。 线程是&#xff1a;一个进程中的执行场景/执行单元。 注意&#xff1a;一个进程可以启动多个线程。 eg. 对于java程序来说&#xff0c;当在DOS命令窗口中…

count/count if函数的基本用法

count函数&#xff0c;用来计算单元格的数的个数&#xff0c;只是用来计数&#xff0c;并且只有只记录数子的个数&#xff0c;文本的个数是不被记录的。 但是很少会用到单纯的count函数&#xff0c;往往在工作中计数是带有条件的。就会用到countif函数 COUNTIF函数需要注意的点…

EXCEL COUNTIF()的一些奇特的用法

文章目录 前言一、统计第几次重复二、统计不重复的数量三、通配符模糊统计四、防止重复录入五、忽略错误值或空值统计六、重复值填充背景色总结 前言 日常工作中需要度娘很多知识点或者方法&#xff0c;但每次用了就忘&#xff0c;下次遇到就需要继续度娘&#xff0c;故在此记…

Excel多条件计数——COUNTIFS【获奖情况统计】

问题描述 当前&#xff0c;我们需要对表格中的获奖情况进行统计 奖励级别&#xff1a;院级、校级、国家级、国际级奖励内容&#xff1a;特等奖、一等奖、二等奖、三等奖、优胜奖 功能要求 对所有奖励级别进行统计根据级别&#xff0c;计算内容数量 当有人的选项内容如下时 …