缘由
apue这本书看了这么久,例子代码也写了一堆堆。直到看到数据库函数库这一章算是真正的让我兴奋了,写了那么多api,终于能用来实实在在做出一个东西来了,而且做的东西非常叼哦,是数据库。不过今天正准备着先跑跑程序和看看源码来着,确发现怎么也运行不了。
这是因为我单独把我自己以为需要的文件:apue_db.h和db.c拷在我自己写的代码的文件,然后直接编译,结果一大堆错误,发现无论如何也运行不了。
正确的做法
首先自我批评一下,每次下载到了什么文件,也不看看README,像下载的apue.2e的源码包,我解压后,直接拿了里面apue.h就开始自己编列子代码,直到这个db.c跑不动,才一头雾水。正确的做法如下:
- 读读apue.2e下README
- 发现其让我修改对应的Make.defines.*的文件,我的就是linux的,WKDIR部分
- WKDIR=/home/asd/Downloads/apue.2e 将这一部分改为apue.2e的文件所在
- 然后直接在apue.2e/的文件夹下使用键入make
到此为止,源码已经编译好了。更多内容,您可参考:APUE源码编绎及执行
运行第二十章的数据库函数库的例子代码
makefile
进入apue.2e/db文件夹下,编写makefile文件,参考了 A small library for databas
all: t4
t4: t4.c libapue_db.a
gcc -g -D_DEBUG_ -I../include -L../lib/ -L. t4.c libapue_db.a ../lib/libapue.a -o t4
libapue_db.a: db.c
gcc -I../include -D_DEBUG_ -Wall -c db.c
ar rsv libapue_db.a db.o
然后直接运行make,即完成了t4.c代码内的内容。t4.c的代码也就是书中571页 程序清单20-1 建立一个数据库并向其中写三条记录 的内容。
不过现在我想稍稍解释一下这个makefile的内容:
- 当头文件与gcc不在同一目录下要用 -I dir参数,它是指头文件所在的目录。而添加库文件时需要 -L dir参数,它指定库文件所在的目录。
来自:gcc的参数 -I和-L 的用法 - -D_DEBUG_ 的意思是相当于定义了DEBUG的宏,会涉及预定义的问题。gcc -D:gcc的预定义功能
- -Wall 打开gcc的所有警告 w代表warn,后面一个all不言而喻
- -c 只编译不链接,只是产生obj文件,以.o结尾,所以产生了db.o文件
- ar -rsv 用于生成静态库文件,上面那个libapue_db,a就是生成的静态库文件
- -L. t4.c libapue_db.a 是将t4.c和libapue_db.a这个库文件Link起来 ,但是man文件上说-L是和路径一起用,-l是和库文件一起用,但是我修改了上面这个makefile也不启什么作用,奇怪。下周二问一下老师。 gcc -l参数和-L参数 按照这个文章改了也没什么用
- 大概意思都懂了,还有一个就为什么
有个.呢-L. t4.c libapue_db.a
- Linux下动态链接库默认后缀名是".so",静态链接库默认后缀名是“.a”。
例子产生的结果
程序清单20-1 建立一个数据库并向其中写三条记录:
#include "apue.h"
#include "apue_db.h"
#include <fcntl.h>
int
main(void)
{
DBHANDLE db;
if ((db = db_open("db4", O_RDWR | O_CREAT | O_TRUNC,
FILE_MODE)) == NULL)
err_sys("db_open error");
if (db_store(db, "Alpha", "data1", DB_INSERT) != 0)
err_quit("db_store error for alpha");
if (db_store(db, "beta", "Data for beta", DB_INSERT) != 0)
err_quit("db_store error for beta");
if (db_store(db, "gamma", "record3", DB_INSERT) != 0)
err_quit("db_store error for gamma");
db_close(db);
exit(0);
}
这样会产生两个文件一个是索引文件db4.dx 和db4.dat,可以cat,但是我cat出来的结果和书上不太一样:
asd@asd-desktop:~/Downloads/apue.2e/db$ cat db4.idx
0 0 0 0 0 0 0 0 0 0 0 0 829 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 869 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 849 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 10Alpha:0:6
0 10beta:6:14
0 11gamma:20:8
asd@asd-desktop:~/Downloads/apue.2e/db$ cat db4.dat
data1
Data for beta
record3
asd@asd-desktop:~/Downloads/apue.2e/db$
我个人认为是我打印的结果是对的,按照书上的说法,11gamma:20:8之前是17,但是很奇怪的我在插入三条数据的时候并没有指明哪两条是在一个散列链上,所以我认为三条记录分别存在在不同的散列链上。才会产生这样的结果。而我的结果就是三条记录在不同的散列链上。
到此,代码可以运行了,下一步就是看懂代码和做课后练习题了。