linux库文件编写入门

上传人:ji****72 文档编号:37520840 上传时间:2018-04-17 格式:DOCX 页数:8 大小:20.35KB
返回 下载 相关 举报
linux库文件编写入门_第1页
第1页 / 共8页
linux库文件编写入门_第2页
第2页 / 共8页
linux库文件编写入门_第3页
第3页 / 共8页
linux库文件编写入门_第4页
第4页 / 共8页
linux库文件编写入门_第5页
第5页 / 共8页
点击查看更多>>
资源描述

《linux库文件编写入门》由会员分享,可在线阅读,更多相关《linux库文件编写入门(8页珍藏版)》请在金锄头文库上搜索。

1、作者: laomai 地址: http:/ 写的“linux 静态/动态链接库的创建和使用“ 地址 http:/ 动态链接库高级应用“ 地址 http:/ ) 在此一并致谢。一、为什么要使用库文件 我们在实际编程工作中肯定会遇到这种情况:有几个项目里有一些函数模块的功能相同, 实现代码也相同,也是我们所说的重复代码。比如,很多项目里都有一个用户验证的功能。代码段如下:/userlogin.h 文件,提供函数声明int isvaliduser(char* username, int namelen);/userlogin.c 文件,实现对用户信息的验证int isvaliduser(char*

2、username, int namelen)int isvalid = 0;/*下面是具体的处理代码,略去*/return isvalid如果每个项目都保存着这两个 userlogin.h 和 userlogin.c 文件,会有以下几个 弊端:1、每个项目里都有重复的模块,造成代码重复。 2、代码的重用性不好,一旦 isvaliduser 的代码发生了变化,为了保持设计的一致性, 我们还要手工修改其他项目里的 userlogin.c 文件,既费时又费力,还容易出错。 库文件就是对公共代码的一种组织形式。 为了解决上面两个弊端,就提出了用库文件存放公共代码的解决方案,其要点就是 把公共的(也就是

3、可以被多次复用的)目标代码从项目中分离出来,统一存放到库文件中,项目要用到这些代码的时候,在编译或者运行的时候从库文件中取得目标代码即可。库文 件 又分两种:静态库和动态库。 二、静态库与动态库如果程序是在编译时加载库文件的,就是使用了静态库。如果是在运行时加载目标代码,就成为动态库。换句话说,如果是使用静态库,则静态库代码在编译时就拷贝到了程序的代码段, 程序的体积会膨胀。如果使用动态库,则程序中只保留库文件的名字和函数名,在运行时 去查找 库文件和函数体,程序的体积基本变化不大。静态库的原则是“以空间换时间” ,增加程序体积,减少运行时间;动态库则是“以时间换空间” ,增加了运行时间,但减

4、少了程序本身的体积。下面我们就以实际例子来看看如何使用这两种库.三、静态库的编写和使用 1、概述静态库文件的扩展名一般为.a,其编写步骤很简单。 编写函数代码 编译生成各目标文件 用 ar 文件对目标文件归档,生成静态库文件。注意归档文件名必须以 lib 打头。使用要点:在 gcc 的-i 参数后加上静态库头文件的路径。在 gcc 的-l 参数后加上库文件所在目录在 gcc 的-l 参数后加上库文件名,但是要去掉 lib 和.a 扩展名。比如库文件名是 libtest.a 那么参数就是 -l test2、编写最简单的静态库文件编写如下两个文件,注意放在同一目录中 myalib.h /静态库头文

5、件myalib.c /静态库实现文件/myalib.h 文件的内容 void test();/myalib.c 文件的内容 #inlcude void test() printf(“testn“); 3、制作库文件 生成目标文件gcc -c myalib.c执行完后会生成一个 myalib.o 文件 用 ar 命令归档,格式为 ar -rc 再次提醒,归档文件名一定要以 lib 打头, .a 结尾。ar -rc libtest.a myalib.o执行完后会生成一个 libtest.a 文件4、使用库文件 编写一个测试程序 main.c,内容为 /main.c 测试静态库调用的程序 #incl

6、ude “myalib.h“ /要把函数的头文件包含进来,否则编译时会报错int main(int argc,char* argv) test();return 0; 编译目标文件,注意要把静态库头文件的路径加到-i 参数里面gcc -i /root/exercise -o main.o -c main.c现在生成了一个 main.o 文件 生成可执行文件,注意要把静态库文件的路径加到-l 参数里面, 把库文件名(去掉打头的 lib 和结尾的.a)加到-l 参数后面。如下面所示gcc -o main -l/root/exercise main.o -ltest此时就会生成一个名为 main 的

7、可执行文件另外,注意- l 参数好象应该加到输入文件名的后面,否则会报错。比如 gcc -o main -l/root/exercise -ltest main.o 就会提示main.o(.text+0x11): in function main: undefined reference to testcollect2: ld returned 1 exit status原因我还不清楚:-) 执行可执行文件查看效果执行./main, 输出test说明执行成功。四、动态库的编写 1、概述动态库一般以.so 结尾,就是 shared object 的意思.其基本生成步骤为编写函数代码编译生成动态库

8、文件,要加上 -shared 和 -fpic 选项 ,库文件名以 lib 开头, 以.so 结尾。使用方式分为两种: 隐式调用和显示调用 隐式调用类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf;显示调用则是在主程序里使用 dlopen、dlsym、dlerror、dlclose 等系统函数。具体的调用方式会在 “五、动态库的调用“ 中详细说明. 2、编写最简单的动态库文件为了便于对照, 我们仍然采用静态库中的文件做例子.编写如下两个文件,注意放在同一目录中 myalib.h /静态库头文件myalib.c /静态库实现文件/myalib.h 文件的内容 void

9、 test();/myalib.c 文件的内容 #inlcude void test() printf(“testn“); 3、编译生成动态库 ,库文件名以 lib 开头, 以.so 结尾。 gcc -fpic -shared -o libtest.so myalib.c此时就生成一个 libtest.so 文件五、动态库的隐式调用隐式调用的含义是代码里不出现库文件名,就是说这个代码和调用静态库的代码是类似的。 1、编写测试文件 /main.c 测试动态库隐式调用的程序 #include “myalib.h“ /要把函数的头文件包含进来,否则编译时会报错int main(int argc,ch

10、ar* argv) test();return 0; 2、 编译测试程序,与静态库类似,要把头文件的路径加到-i 参数里面gcc -i /root/exercise -o main.o -c main.c现在生成了一个 main.o 文件 3、连接生成测试程序 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:

11、no such file or directory。这个原因就是程序运行时并不知道动态库所在的路径,因此自然找不到。解决这个问题的办法有三种。见下节 六、使动态库被系统共享的三种办法(再次说明: 本节参考了计算机世界网雨亦奇的文章“linux 动态链接库高级应用“地址 http:/ (1)拷贝动态链接库到系统共享目录下,或在系统共享目录下为该动态链接库建立连接(硬连接或符号连接均可,常用符号连接).这里说的系统共享目录,指的是 linux 动态链接库存放的目录,包括/lib,/usr/lib 以及/etc/ld.so.conf 文件内所列的一系列目录.实例:执行 # cp libtest.so

12、 /lib # ldconfig 或: # ln -s pwd/libtest.so /lib # ldconfig 注意 pwd 前后有两个反引号,其目的是取得 pwd 命令的输出,即当前目录.此时再执行 main,即可成功.(2)将动态链接库所在目录名追加到动态链接库配置文件/etc/ld.so.conf 中. # pwd /etc/ld.so.conf # ldconfig 此时再执行 main,即可成功.(3)利用动态链接库管理命令 ldconfig,强制其搜索指定目录,并更新缓存文件,便于动态装入. # ldconfig pwd 此时再执行 main,即可成功.要注意,第三种方法虽然

13、有效,但效果是暂时的,供程序测试还可以,一旦再度运行 ldconfig,则缓存文件内容可能改变,所需的动态链接库可能不被系统共享了.而且无论哪种办法,其实质都是用 ldconfig 命令把动态库文件所在路径加入到系统库列表中,(前两种永久,第三种临时)七、动态库的显式调用显式调用的含义是代码出现库文件名,用户需要自己去打开和管理库文件。其要点为:把 dlfcn.h 系统头文件包含进来用 dlopen 函数打开库文件,并指定打开方式 dllope 的的第一个参数为共享库的名称,将会在下面位置查找指定的共享库。环境变量 ld_library_path 列出的用分号间隔的所有目录。文件/etc/ld

14、.so.cache 中找到的库的列表,由 ldconfig 命令刷新。目录 usr/lib。目录/lib。当前目录。 第二个参数为打开共享库的方式。有两个取值rtld_now:将共享库中的所有函数加载到内存rtld_lazy:会推后共享库中的函数的加载操作,直到调用 dlsym()时方加载某函数用 dlerror()函数测试是否打开成功,并进行错误处理;用 dlsym 获得函数地址,存放在一个函数指针中用获得的函数指针进行函数调用。程序结束时用 dlclose 关闭打开的动态库,防止资源泄露。用 ldconfig 工具把动态库的路径加到系统库列表中1、编写测试文件 /main.c 测试动态库显

15、式调用的程序 #include /用于动态库管理的系统头文件 #include “myalib.h“ /要把函数的头文件包含进来,否则编译时会报错int main(int argc,char* argv) /声明对应的函数的函数指针void (*ptest)(); /加载动态库void *pdlhandle = dlopen(“libtest.so“, rtld_lazy); /错误处理if(pdlhandle = null ) printf(“failed load libraryn“);return -1;char* pszerr = dlerror();if(pszerr != null)printf(“%sn“, pszerr);return -1;/获取函数的地址ptest = dlsym(pdlhandle, “test“); pszerr = dlerror();if(pszerr != null)printf(“%sn“, pszerr);dl

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号