实验10 编写库文件.ppt_第1页
实验10 编写库文件.ppt_第2页
实验10 编写库文件.ppt_第3页
实验10 编写库文件.ppt_第4页
实验10 编写库文件.ppt_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、编写库文件,为什么要编写库文件,每个项目里都有重复的模块,造成代码重复。 而且,代码的重用性不好,一旦变化,为了保持设计的一致性,必须手动逐个修改。 库文件就是对公共代码的一种组织形式。 比如,一个用户验证功能的库文件: /userlogin.h文件,提供函数声明 int isvaliduser(char* username, int namelen); /userlogin.c文件,实现对用户信息的验证 int isvaliduser(char* username, int namelen) int isvalid = 0; /*下面是具体的处理代码,略去*/ return isvalid

2、,库文件分类,静态库:程序在编译时加载库文件,即静态库代码在编译时就拷贝到了程序的代码段,程序的体积会膨胀。 “以空间换时间”。 动态库:程序在运行时加载目标代码,即程序中只保留库文件的名字和函数名,在运行时去查找库文件和函数体,程序的体积基本变化不大。 “以时间换空间”。,静态库的编写要点,静态库文件的扩展名一般为.a,其编写步骤为: 编写函数代码 编译生成各目标文件 用ar文件对目标文件归档,生成静态库文件 注意归档文件名必须以lib打头 使用要点: 在gcc 的-i参数后加上静态库头文件的路径 在gcc 的-l参数后加上库文件所在目录 在gcc 的-l参数后加上库文件名,但是要去掉lib

3、和.a扩展名 比如库文件名是libtest.a 那么参数就是 -l test,示例编写静态库,编写如下两个文件,注意放在同一目录中 myalib.h /静态库头文件 myalib.c /静态库实现文件 /myalib.h 文件的内容 void test(); /myalib.c 文件的内容 #inlcude void test() printf(testn); ,示例制作静态库,生成目标文件 gcc -c myalib.c 执行完后会生成一个myalib.o文件 用ar命令归档,格式为ar -rc 再次提醒,归档文件名一定要以lib打头, .a结尾。 ar -rc libtest.a myal

4、ib.o 执行完后会生成一个libtest.a文件,示例使用静态库,编写一个测试程序main.c,内容为: #include myalib.h /要把函数的头文件包含进来,否则编译时会报错 int main(int argc,char* argv) test(); return 0; 编译目标文件,注意要把静态库头文件的路径加到-i参数里面 gcc -i /root/exercise -o main.o -c main.c 生成可执行文件,注意要把静态库文件的路径加到-l参数里面, 把库文件名(去掉打头的lib和结尾的.a)加到-l参数后面 gcc -o main -l/root/exerci

5、se main.o ltest 执行可执行文件查看效果./main,动态库的编写要点,动态库一般以.so结尾,就是shared object的意思 基本生成步骤为: 编写函数代码 编译生成动态库文件,要加上 -shared 和 -fpic 选项,库文件名以lib开头, 以.so 结尾 使用方式分为两种:隐式调用和显示调用 隐式调用:类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf 显示调用:在主程序里使用dlopen、dlsym、dlerror、dlclose等系统函数,示例编写动态库(与前面一样),编写如下两个文件,注意放在同一目录中 myalib.h /静态库

6、头文件 myalib.c /静态库实现文件 /myalib.h 文件的内容 void test(); /myalib.c 文件的内容 #inlcude void test() printf(testn); ,示例制作,编译生成动态库,库文件名以lib开头,以.so 结尾。 gcc -fpic -shared -o libtest.so myalib.c 此时就生成一个libtest.so文件,示例动态库的隐式调用,1、编写测试文件,与前面一样 2、编译测试程序,与静态库类似,要把头文件的路径加到-i参数里面 gcc -i /root/exercise -o main.o -c main.c 现

7、在生成了一个main.o文件 3、连接生成测试程序,注意要把库文件的路径加到-l参数里面 gcc -o main -l/root/exercise main.o -ltest 现在生成了一个main文件 4、执行测试程序 ./main 此时出现提示 ./main: error while loading shared libraries: libtest.so: cannot open shared object file: no such file or directory。 这个原因就是程序运行时并不知道动态库所在的路径,因此自然找不到。解决这个问题的办法有三种,见下页,方法一,拷贝动态链

8、接库到系统共享目录下,或在系统共享目录下为该动态链接库建立连接(硬连接或符号连接均可,常用符号连接)。这里说的系统共享目录,指的是linux动态链接库存放的目录,包括 /lib、/usr、/lib以及/etc/ld.so.conf文件内所列的一系列目录 实例:执行 # cp libtest.so /lib # ldconfig 或: # ln -s pwd/libtest.so /lib # ldconfig 注意pwd前后有两个反引号,其目的是取得pwd命令的输出,即当前目录。此时再执行main,即可成功,方法二,将动态链接库所在目录名追加到动态链接库配置文件/etc/ld.so.conf中

9、 # pwd /etc/ld.so.conf # ldconfig 此时再执行main,即可成功,方法三,利用动态链接库管理命令ldconfig,强制其搜索指定目录,并更新缓存文件,便于动态装入 # ldconfig pwd 此时再执行main,即可成功 注意:第三种方法虽然有效,但效果是暂时的,供程序测试还可以,一旦再度运行ldconfig,则缓存文件内容可能改变,所需的动态链接库可能不被系统共享了 无论哪种办法,其实质都是用ldconfig命令把动态库文件所在路径加入到系统库列表中,(前两种永久,第三种临时),动态库的显式调用要点(1),代码出现库文件名,用户需要自己去打开和管理库文件。要

10、点为: 把dlfcn.h系统头文件包含进来 用dlopen函数打开库文件,并指定打开方式 dllope的的第一个参数为共享库的名称,将会在下面位置查找指定的共享库。 环境变量ld_library_path列出分号间隔的所有目录 文件/etc/ld.so.cache中找到的库的列表,由ldconfig命令刷新 目录/usr/lib 目录/lib 当前目录,动态库的显式调用要点(2),第二个参数为打开共享库的方式。有两个取值: rtld_now:将共享库中的所有函数加载到内存 rtld_lazy:会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数 用dlerror()函数测试是否

11、打开成功,并进行错误处理 用dlsym获得函数地址,存放在一个函数指针中 用获得的函数指针进行函数调用 程序结束时用dlclose关闭打开的动态库,防止资源泄露 用ldconfig工具把动态库的路径加到系统库列表中,示例编写测试文件,示例编译和执行测试文件,编译测试文件 使用-ldl选项指明生成的对象模块需要使用共享库 gcc -o main -ldl main.c 执行完后就生成了一个main文件 执行测试程序 ./main 输出 test 说明成功,提示(1),无论是动态库的显式调用还是隐式调用,都需要用ldconfig工具将动态库的路径加到系统库列表中,否则运行时会出错 可以用ldd命令

12、检查程序都使用到哪些共享库,ldd命令行用法如下: ldd -version -v|-verbose -d|-data-relocs -r|-function-relocs -help file. -version : 此选项用于打印出ldd的版本号 -v 或 -verbose : 此选项指示ldd输出关于所依赖的动态链接库的尽可能详细的信息 -d 或 -data-relocs : 此选项执行重定位,并且显示不存在的函数. -r 或 -function-relocs : 此选项执行数据对象与函数的重定位,同时报告不存在的对象 -help : 此选项用于打印出ldd的帮助信息,提示(2),用静态

13、库连接时的结果 #ldd main libc.so.6 = /lib/tls/libc.so.6 (0 xb74ad000) /lib/ld-linux.so.2 = /lib/ld-linux.so.2 (0 xb75eb000) 可见使用静态库时,由于库已经被编译成程序的一部分,因此ldd的输出中就只有用到的系统库,提示(3),用动态库隐式连接时的结果 libtest.so = /root/exercise/libtest.so (0 xb75e2000) libc.so.6 = /lib/tls/libc.so.6 (0 xb74ab000) /lib/ld-linux.so.2 = /lib/ld-linux.so.2 (0 xb75eb000) 可见隐式使用动态库时,所有用到的动态库(包括系统和用户的)都会被显示出来,提示(4),动态库显式连接时的结果 ldd

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论