本文共 6837 字,大约阅读时间需要 22 分钟。
1、查看库文件是由哪个软件包提供的
空闲时打开/usr/lib目录(因为我知道这个目录下放着一些库文件,是我们开发者可以利用的)想看看我的系统中有哪些库。
看到一个libz.so,于是用命令查看:
此命令输出如下信息:
zlib1g-dev: /usr/lib/libz.so |
即我的系统中软件包zlib1g-dev提供了libz.so这个库文件。
2、查看软件包的详细信息
可以用下列命令查看此软件包是干什么的:
apt-cache show zlib1g-dev |
输出内容一部分为:
Description: compression library - developmentzlib is a library implementing the deflate compression method foundin gzip and PKZIP. This package includes the development supportfiles.Bugs: mailto:ubuntu-users@lists.ubuntu.comOrigin: Ubuntu |
显然这个软件包提供了用gzip和PKZIP压缩算法进行开发的相关东西。
继续用下面的命令查看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库文件提供哪些调用:
此命令输出如下:
00001810 T adler3200001ad0 T adler32_combine00013b30 A __bss_startU clearerr00001c70 T compress00001ba0 T compress200001b80 T compressBound00001cd0 T crc3200002320 T crc32_combinew __cxa_finalize00005da0 T deflate00005150 T deflateBound00004bb0 T deflateCopy000107e0 R deflate_copyright00004890 T deflateEnd00005640 T deflateInit_00005360 T deflateInit2_00006b80 T deflateParams00004810 T deflatePrime000051c0 T deflateReset00004fe0 T deflateSetDictionary000047e0 T deflateSetHeader00004850 T deflateTune00010820 R _dist_code00013b30 A _edata00013b34 A _endU __errno_locationU fcloseU fdopenU feofU ferrorU fflush0000e784 T _finiU fopenU fprintfU fputcU freadU freeU fseekU ftellU fwrite00001cb0 T get_crc_tablew __gmon_start__00002570 T gzclearerr00002b50 T gzclose00002550 T gzdirect00003ba0 T gzdopen00002520 T gzeof000025b0 T gzerror00002d40 T gzflush000046c0 T gzgetc00004640 T gzgets00003c20 T gzopen00002a10 T gzprintf00002900 T gzputc000028c0 T gzputs00003c40 T gzread00002950 T gzrewind00004410 T gzseek00002ab0 T gzsetparams00004600 T gztell000024d0 T gzungetc000027d0 T gzwrite0000a490 T inflate0000c4e0 T inflateBack0000c490 T inflateBackEnd0000c390 T inflateBackInit_0000a000 T inflateCopy00012720 R inflate_copyright00009f40 T inflateEnd0000e1c0 T inflate_fast00009fa0 T inflateGetHeader00009f00 T inflateInit_00009df0 T inflateInit2_00009da0 T inflatePrime00009d00 T inflateReset0000a380 T inflateSetDictionary0000c1a0 T inflateSync00009fd0 T inflateSyncPoint0000d770 T inflate_table000013d0 T _initw _Jv_RegisterClasses00010a20 R _length_codeU mallocU memcpyU memsetU sprintfU __stack_chk_failU strcatU strcpyU strerrorU strlen00008390 T _tr_align00009240 T _tr_flush_block000074e0 T _tr_init00008210 T _tr_stored_block00007c10 T _tr_tally00004710 T uncompressU vsnprintf00009cd0 T zcalloc00009ca0 T zcfree00013900 D z_errmsg00009c70 T zError00009c60 T zlibCompileFlags00009c40 T zlibVersion |
这些输出中的第一列是这个库libz.so提供的调用的值,第二列是调用的类型,第三列是调用的名称(可理解为我们常说的函数名)。
关于nm的详细用法可以参考man nm手册,我们在这里先只关心一下第二列为T的,即类型为T的,这是我们的应用程序可以调用的。
/************关于本文档********************************************
*filename: 我是这样学习Linux下C语言编程的-自我学会利用Linux系统上已有的开发库
*purpose: 说明怎样利用Linux中已有的库文件进行开发
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(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 gzclearerr00002b50 T gzclose00002550 T gzdirect00003ba0 T gzdopen00002520 T gzeof000025b0 T gzerror00002d40 T gzflush000046c0 T gzgetc00004640 T gzgets00003c20 T gzopen00002a10 T gzprintf00002900 T gzputc000028c0 T gzputs00003c40 T gzread00002950 T gzrewind00004410 T gzseek00002ab0 T gzsetparams00004600 T gztell000024d0 T gzungetc000027d0 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 parameteris 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' forHuffman only compression as in "wb1h", or 'R' for run-length encodingas in "wb1R". (See the description of deflateInit2 for more informationabout the strategy parameter.)gzopen can be used to read a file which is not in gzip format; in thiscase gzread will directly read from the file without decompression.gzopen returns NULL if the file could not be opened or if there wasinsufficient memory to allocate the (de)compression state; errnocan be checked to distinguish the two cases (if errno is zero, thezlib 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的压缩文件。
你可以打开此压缩文件看看,里面是不是你自己写进去的信息呢?
转载地址:http://eczvb.baihongyu.com/