libz.so库分析

from:http://blog.chinaunix.net/uid-12773189-id-84605.html

1、查看库文件是由哪个软件包提供的
空闲时打开/usr/lib目录(因为我知道这个目录下放着一些库文件,是我们开发者可以利用的)想看看我的系统中有哪些库。
看到一个libz.so,于是用命令查看:dpkg -S /usr/lib/libz.so

此命令输出如下信息:zlib1g-dev: /usr/lib/libz.so

即我的系统中软件包zlib1g-dev提供了libz.so这个库文件。
2、查看软件包的详细信息
可以用下列命令查看此软件包是干什么的:apt-cache show zlib1g-dev

输出内容一部分为:Description: compression library - development
zlib is a library implementing the deflate compression method found
in gzip and PKZIP. This package includes the development support
files.
Bugs: mailto:[email protected]
Origin: Ubuntu

显然这个软件包提供了用gzip和PKZIP压缩算法进行开发的相关东西。

继续用下面的命令查看zlib1g-dev软件包的详细信息:dpkg -L zlib1g-dev

此命令输出如下信息:/.
/usr
/usr/lib
/usr/lib/libz.a
/usr/include
/usr/include/zlib.h
/usr/include/zconf.h
/usr/share
/usr/share/doc
/usr/share/doc/zlib1g-dev
/usr/share/doc/zlib1g-dev/examples
/usr/share/doc/zlib1g-dev/examples/example.c.gz
/usr/share/doc/zlib1g-dev/examples/contrib.tar.gz
/usr/share/doc/zlib1g-dev/examples/minigzip.c.gz
/usr/share/doc/zlib1g-dev/changelog.gz
/usr/share/doc/zlib1g-dev/FAQ.gz
/usr/share/doc/zlib1g-dev/README.gz
/usr/share/doc/zlib1g-dev/copyright
/usr/share/doc/zlib1g-dev/changelog.Debian.gz
/usr/share/doc/zlib1g-dev/algorithm.txt.gz
/usr/share/man
/usr/share/man/man3
/usr/share/man/man3/zlib.3.gz
/usr/lib/libz.so

从这里可以看出,zlib1g-dev软件包提供了库文件libz.a和libz.so,还提供了头文件zlib.h和zconf.h,另外还在/usr/share/doc/zlib1g-dev目录下提供关于此库文件使用方法的文档,甚至有例子在/usr/share/doc/zlib1g-dev/examples目录下,比如example.c.gz就是一个完整的gzip压缩/解压缩例子。
如果把example.c.gz、minigzip.c.gz两个例子程序完全弄懂了,你就肯定会自己写程序进行压缩和解压缩工作了。
3、查看库文件提供了哪些调用
如果我们不看上面的软件包信息中提供的源代码例子,也可以用nm命令自己查看库文件提供了哪些调用。
比如我们用下面的nm命令查看libz.so库文件提供哪些调用:nm -D /usr/lib/libz.so

此命令输出如下:00001810 T adler32
00001ad0 T adler32_combine
00013b30 A __bss_start
U clearerr
00001c70 T compress
00001ba0 T compress2
00001b80 T compressBound
00001cd0 T crc32
00002320 T crc32_combine
w __cxa_finalize
00005da0 T deflate
00005150 T deflateBound
00004bb0 T deflateCopy
000107e0 R deflate_copyright
00004890 T deflateEnd
00005640 T deflateInit_
00005360 T deflateInit2_
00006b80 T deflateParams
00004810 T deflatePrime
000051c0 T deflateReset
00004fe0 T deflateSetDictionary
000047e0 T deflateSetHeader
00004850 T deflateTune
00010820 R _dist_code
00013b30 A _edata
00013b34 A _end
U __errno_location
U fclose
U fdopen
U feof
U ferror
U fflush
0000e784 T _fini
U fopen
U fprintf
U fputc
U fread
U free
U fseek
U ftell
U fwrite
00001cb0 T get_crc_table
w __gmon_start__
00002570 T gzclearerr
00002b50 T gzclose
00002550 T gzdirect
00003ba0 T gzdopen
00002520 T gzeof
000025b0 T gzerror
00002d40 T gzflush
000046c0 T gzgetc
00004640 T gzgets
00003c20 T gzopen
00002a10 T gzprintf
00002900 T gzputc
000028c0 T gzputs
00003c40 T gzread
00002950 T gzrewind
00004410 T gzseek
00002ab0 T gzsetparams
00004600 T gztell
000024d0 T gzungetc
000027d0 T gzwrite
0000a490 T inflate
0000c4e0 T inflateBack
0000c490 T inflateBackEnd
0000c390 T inflateBackInit_
0000a000 T inflateCopy
00012720 R inflate_copyright
00009f40 T inflateEnd
0000e1c0 T inflate_fast
00009fa0 T inflateGetHeader
00009f00 T inflateInit_
00009df0 T inflateInit2_
00009da0 T inflatePrime
00009d00 T inflateReset
0000a380 T inflateSetDictionary
0000c1a0 T inflateSync
00009fd0 T inflateSyncPoint
0000d770 T inflate_table
000013d0 T _init
w _Jv_RegisterClasses
00010a20 R _length_code
U malloc
U memcpy
U memset
U sprintf
U __stack_chk_fail
U strcat
U strcpy
U strerror
U strlen
00008390 T _tr_align
00009240 T _tr_flush_block
000074e0 T _tr_init
00008210 T _tr_stored_block
00007c10 T _tr_tally
00004710 T uncompress
U vsnprintf
00009cd0 T zcalloc
00009ca0 T zcfree
00013900 D z_errmsg
00009c70 T zError
00009c60 T zlibCompileFlags
00009c40 T zlibVersion

这些输出中的第一列是这个库libz.so提供的调用的值,第二列是调用的类型,第三列是调用的名称(可理解为我们常说的函数名)。
关于nm的详细用法可以参考man nm手册,我们在这里先只关心一下第二列为T的,即类型为T的,这是我们的应用程序可以调用的。
/************关于本文档********************************************
*filename: 我是这样学习Linux下C语言编程的-自我学会利用Linux系统上已有的开发库
*purpose: 说明怎样利用Linux中已有的库文件进行开发
*wrote by: zhoulifa([email protected]) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-02-06 20:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to:Google
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
同时由于我们只关心gzip压缩和解压缩方法的使用,我们可以用命令过滤一下:nm -D /usr/lib/libz.so | grep gz

此命令输出如下:00002570 T gzclearerr
00002b50 T gzclose
00002550 T gzdirect
00003ba0 T gzdopen
00002520 T gzeof
000025b0 T gzerror
00002d40 T gzflush
000046c0 T gzgetc
00004640 T gzgets
00003c20 T gzopen
00002a10 T gzprintf
00002900 T gzputc
000028c0 T gzputs
00003c40 T gzread
00002950 T gzrewind
00004410 T gzseek
00002ab0 T gzsetparams
00004600 T gztell
000024d0 T gzungetc
000027d0 T gzwrite

显然,如果你有在Linux下用C语言编程操作过文件,对上面出现的函数名,应该很熟悉吧?把前面的gz换成f,是不是多数都是你熟悉的stdio.h提供的文件操作函数?如果直接去掉gz,是不是就是fcntl.h提供的所有文件操作函数?
4、查看函数的定义
打开/usr/include/zlib.h,搜索上面出现的这些函数,你很快会找gzopen的说明的:ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
/*
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb") but can also include a compression level
("wb9") or a strategy: ‘f‘ for filtered data as in "wb6f", ‘h‘ for
Huffman only compression as in "wb1h", or ‘R‘ for run-length encoding
as in "wb1R". (See the description of deflateInit2 for more information
about the strategy parameter.)

gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression.

gzopen returns NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR). */

看到了吧?用gzopen函数就可以直接打开或创建一个压缩文件*.gz的,使用方法在这里讲得比较清楚了。
同样,我们会看到上面所有函数的说明:ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len));
ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence));
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
……

5、使用库
有了上面这些信息,我们就可以自己写程序来使用库文件提供的所有东西了。比如下面的代码:#include <zlib.h> /* 因为 gz 相关的函数在这个头文件中定义的 */
#include <zconf.h>
#include <stdio.h> /* 因为 printf 相关的函数在这个头文件中定义的 */
#include <errno.h> /* 因为 errno 相关的函数在这个头文件中定义的 */
#include <stdlib.h> /* 因为 exit 函数在这个头文件中定义的 */
#include <string.h> /* 因为 strlen 函数在这个头文件中定义的 */

int main(int argc, char **argv)
{
        gzFile mygzfp;

mygzfp = gzopen(argv[1], "w");
        if(mygzfp == NULL) {
                printf("以写方式打开文件‘%s‘出错,错误信息:%s", argv[1], strerror(errno));
                exit(0);
        }
        gzwrite(mygzfp, argv[2], strlen(argv[2]));
        gzclose(mygzfp);
        return 0;
}

编译此程序用这个命令:
gcc gzfile.c -lz
注意:为了引用libz.so这个库
文件,我们必须用-lz。
运行这个命令:
./a.out mygzfile.gz "hello, 这是一个自己生成压缩文件的测试程序。"
将在当前目录下生成一个文件名为mygzfile.gz的压缩文件。
你可以打开此压缩文件看看,里面是不是你自己写进去的信息呢?

时间: 2024-11-05 15:57:31

libz.so库分析的相关文章

google-glog 开源库分析(二):glog用法

glog使用 设置符号变量,定制日志行为 具体符号变量的设置看glog介绍中的符号变量 日志系统初始化 初始化函数:google::InitGoogleLogging(argv[0]) 初始化参数一般是第一个命令行参数--即程序的名称 结束时可以调用关闭日志系统函数 关闭日志库函数:google::ShutdownGoogleLogging() 程序运行时,可通过命令行参数或环境变量来控制程序的日志行为 glog APIs: void google::InitGoogleLogging(cons

google-glog 开源库分析(四):glog宏技巧

在核心结构之外,google-glog还通过宏技巧提供统一简洁的使用接口. 同时,通过命名空间的使用尽可能的减少名字冲突,提供一个简介的日志库. 宏助手 通过宏提供一个统一的简洁的日志输出接口 简单的使用如LOG(INFO),LOG(ERROR)等日志输出接口 通过宏提供丰富的日志输出扩展功能 提供了IF,CHECK等助手宏来简化代码 编程技巧 命名空间的使用 因为是作为库使用,所以glog中使用了命名空间类避免名字冲突 通过google命名空间提供glog库的接口空间,内部实现则进一步封装到嵌

缺少libz.dylib库的时候引起的一个链接错误

导入ASI框架,遇到缺少libz.dylib库的时候引起的一个链接错误 Undefined symbols for architecture armv7s: "_inflate", referenced from: -[ASIDataDecompressor uncompressBytes:length:error:] in ASIDataDecompressor.o "_deflate", referenced from: -[ASIDataCompressor

RE写作Issue问题题库分析与提纲

RE写作Issue问题题库分析与提纲 GRE写作Issue问题题库分析与提纲 第一类 社会 2. "Competition is ultimately more beneficial than detrimental to society." 归根结底,竞争对于社会是利多弊少. Generally speaking, competition contributes to progress in society. 1.        Generally speaking, competi

Android media媒体库分析之:MediaProvider

在做Android媒体应用程序时(Audio.Image.Video)需要对Android的媒体提供者(MediaProvider)做详细的分析,下面记录一下我的收获: 一.获取MediaProvider: 该工程在系统源码的packages\providers目录下,提出并导入Eclipse,便于阅读: 图中可见都很多报错的,是滴,因为需要一些系统标准sdk之外的接口,不过不影响我们阅读代码. 二.工程结构及内部关系: 可以从上图看出包含4个文件: MediaScannerService.Ja

利用淘宝IP库分析web日志来源分布

web访问日志中含有来访IP,通过IP查看归属地,最后统计访问的区域分布,可细化到省.市 淘宝接口地址:http://ip.taobao.com/service/getIpInfo.php?ip=14.215.177.38,后面的IP按需修改 例如要查看14.215.177.38这个地址的相关信息,返回的信息如下: {"code":0,"data": {"country":"\u4e2d\u56fd", "count

android下调试3G之Ril库分析

一.基本架构概述 Android RIL (Radio Interface Layer)提供了Telephony服务和Radio硬件之间的抽象层.RIL负责数据的可靠传输.AT命令的发送 以及response(响应)的解析.一般的,应用处理器(AP)通过AT命令集与无线通讯模块(基带/BP)通信.通信的方式又分为主动 请求的request(诸如拨号.发短信--),以及Modem主动上报的例如信号强度.基站信息.来电.来短信等,称之为 unsolicitedresponse(未经请求的响应).系统

Link Binary With Libraries中添加的时候 也找不到libz.dylib 库

接到一个项目4个静态库找不到 在 Link Binary With Libraries中添加的时候 也找不到libz.dylib  郁闷了 原来是ios9后 原来的dylib后缀名的库全部修改tbd 你要是实在想添加 没有不行 那也有办法 NOW 进入你项目的build phases ==>点击+号在弹出的对话框选择addother==>在弹出的对话框中输入"cmd"+"shift"+"g"==>输入/usr/lib==>

EMIPLIB库分析二

前一篇中详细分析了MIPComponentChain类.了解了执行框架的运作情况.还有必要知晓框架的实现细节,以便于真正掌握库的设计意图.有一点有些模糊,就是MIPComponnet间传递数据这一部分.现在只是有个大致的了解.pull component生成消息,push component接收这些消息.仍然以feedbackexample例程为研究对象. feedbackexample例程中,在启动处理过程前,会生成很多MIPComponent,然后依据顺序放入MIPComponentChai