IT猫扑网:您身边最放心的安全下载站! 最新更新| 软件分类| 专题汇总| 手机版

您当前所在位置:IT猫扑网 > 操作系统 > LINUX > linux库文件的制作

linux库文件的制作

时间:2015-06-28 00:00 来源:IT猫扑网|http://www.itmop.com/ 作者:网管联盟 我要评论(0)

  一、为什么要使用库文件

  我们在实际编程工作中肯定会遇到这种情况:有几个项目里有一些函数模块的功能相同,

  实现代码也相同,也是我们所说的重复代码。比如,很多项目里都有一个用户验证的功能。

  代码段如下:

  //UserLogin.h文件,提供函数声明

  int IsValidUser(char* username, int namelen);

  //UserLogin.c文件,实现对用户信息的验证

  int IsValidUser(char* username, int namelen)

  {

  int IsValid = 0;

  /*下面是具体的处理代码,略去*/

  return IsValid

  }

  如果每个项目都保存着这两个UserLogin.h和UserLogin.c文件,会有以下几个

  弊端:

  1、每个项目里都有重复的模块,造成代码重复。

  2、代码的重用性不好,一旦IsValidUser的代码发生了变化,为了保持设计的一致性,

  我们还要手工修改其他项目里的UserLogin.c文件,既费时又费力,还容易出错。

  库文件就是对公共代码的一种组织形式。

  为了解决上面两个弊端,就提出了用库文件存放公共代码的解决方案,其要点就是

  把公共的(也就是可以被多次复用的)目标代码从项目中分离出来,统一存放到库文件中,

  项目要用到这些代码的时候,在编译或者运行的时候从库文件中取得目标代码即可。库文件

  又分两种:静态库和动态库。

  二、静态库与动态库

  如果程序是在编译时加载库文件的,就是使用了静态库。如果是在运行时加载目标代码,

  就成为动态库。换句话说,如果是使用静态库,则静态库代码在编译时就拷贝到了程序的代码段,

  程序的体积会膨胀。如果使用动态库,则程序中只保留库文件的名字和函数名,在运行时去查找

  库文件和函数体,程序的体积基本变化不大。

  静态库的原则是&以空间换时间&,增加程序体积,减少运行时间;

  动态库则是&以时间换空间&,增加了运行时间,但减少了程序本身的体积。

  下面我们就以实际例子来看看如何使用这两种库.

  三、静态库的编写和使用

  1、概述

  静态库文件的扩展名一般为.a,其编写步骤很简单。

  ⑴编写函数代码

  ⑵编译生成各目标文件

  ⑶用ar文件对目标文件归档,生成静态库文件。

  注意归档文件名必须以lib打头。

  使用要点:

  ⑴在gcc 的-I参数后加上静态库头文件的路径。

  ⑵在gcc 的-L参数后加上库文件所在目录

  ⑶在gcc 的-l参数后加上库文件名,但是要去掉lib和.a扩展名。

  比如库文件名是libtest.a 那么参数就是 -l test

  2、编写最简单的静态库文件

  编写如下两个文件,注意放在同一目录中

  myalib.h   //静态库头文件

  myalib.c   //静态库实现文件

  //myalib.h 文件的内容

  void test();

  //myalib.c 文件的内容

  #inlcude

  void test()

  {

  printf(&testn&);

  }

  3、制作库文件

  ⑴生成目标文件

  gcc -c myalib.c

  执行完后会生成一个myalib.o文件

  ⑵用ar命令归档,格式为ar -rc <生成的档案文件名> <.o文件名列表>

  再次提醒,归档文件名一定要以lib打头, .a结尾。

  ar -rc libtest.a myalib.o

  执行完后会生成一个libtest.a文件

  4、使用库文件

  ⑴编写一个测试程序main.c,内容为

  //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

  现在生成了一个main.o文件

  ⑶生成可执行文件,注意要把静态库文件的路径加到-L参数里面,

  把库文件名(去掉打头的lib和结尾的.a)加到-l参数后面。如下面所示

  gcc -o main -L/root/exercise   main.o -ltest

  此时就会生成一个名为main的可执行文件

  另外,注意- l参数好象应该加到输入文件名的后面,否则会报错。

  比如gcc -o main -L/root/exercise   -ltest main.o就会提示

  main.o(.text+0x11): In function `main'':

  : undefined reference to `test''

  collect2: ld returned 1 exit status

  原因我还不清楚:-)

  ⑷执行可执行文件查看效果

  执行./main, 输出

  test

  说明执行成功。

  四、动态库的编写

  1、概述

  动态库一般以.so结尾,就是shared object的意思.

  其基本生成步骤为

  ⑴编写函数代码

  ⑵编译生成动态库文件,要加上 -shared 和 -fpic 选项 ,

  库文件名以lib开头, 以.so 结尾。

  使用方式分为两种: 隐式调用和显示调用

  隐式调用类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf;

  显示调用则是在主程序里使用dlopen、dlsym、dlerror、dlclose等系统函数。

  具体的调用方式会在 &五、动态库的调用& 中详细说明.

  2、编写最简单的动态库文件

  为了便于对照, 我们仍然采用静态库中的文件做例子.

  编写如下两个文件,注意放在同一目录中

  myalib.h   //静态库头文件

  myalib.c   //静态库实现文件

  //myalib.h 文件的内容

  void 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,char* 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: No such file or directory。

  这个原因就是程序运行时并不知道动态库所在的路径,因此自然找不到。

  解决这个问题的办法有三种。见下节

  六、使动态库被系统共享的三种办法

  (再次说明: 本节参考了计算机世界网雨亦奇的文章&LINUX动态链接库高级应用&

  地址http://www.ccw.com.cn/htm/center/prog/02_3_13_3_2.asp)

  (1)拷贝动态链接库到系统共享目录下,或在系统共享目录下为该动态链接库

  建立连接(硬连接或符号连接均可,常用符号连接).这里说的系统共享目录,

  指的是LINUX动态链接库存放的目录,包括

  /lib,/usr/lib以及/etc/ld.so.conf文件内所列的一系列目录.

#p#副标题#e#

  实例:执行

  # cp libtest.so /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,即可成功.

  要注意,第三种方法虽然有效,但效果是暂时的,供程序测试还可以,一旦再度运行ldconfig,

  则缓存文件内容可能改变,所需的动态链接库可能不被系统共享了.

  而且无论哪种办法,其实质都是用ldconfig命令把动态库文件

  所在路径加入到系统库列表中,(前两种永久,第三种临时)

  补充:ldconfig命令的作用(见最后说明)

关键词标签:linux库文件

相关阅读 安装红帽子RedHat Linux9.0操作系统教程 Tomcat9.0如何安装_Tomcat9.0环境变量配置方法 多种操作系统NTP客户端配置 Linux操作系统修改IP Linux实现SCSI硬盘热插拔及在线识别 Linux下用CDMA modem拨号上网

文章评论
发表评论

热门文章 安装红帽子RedHat Linux9.0操作系统教程 安装红帽子RedHat Linux9.0操作系统教程 Linux服务器:设计高性能网站架构-LLMP Linux服务器:设计高性能网站架构-LLMP 使用Clonezilla迁移到虚拟Linux环境 使用Clonezilla迁移到虚拟Linux环境 Linux上的MRTG流量监控中心 Linux上的MRTG流量监控中心 Linux 双网卡绑定一个IP原理及实现 Linux 双网卡绑定一个IP原理及实现 linux和windows等系统远程控制ubuntu桌面 linux和windows等系统远程控制ubuntu桌面

相关下载

人气排行 Linux下获取CPUID、硬盘序列号与MAC地址 dmidecode命令查看内存型号 linux tc实现ip流量限制 安装红帽子RedHat Linux9.0操作系统教程 linux下解压rar文件 lcx.exe、nc.exe、sc.exe入侵中的使用方法 Ubuntu linux 关机、重启、注销 命令 查看linux服务器硬盘IO读写负载 linux命令行浏览器的使用方法 Linux NFS服务固定端口及防火墙配置 U盘安装Ubuntu 10.04 Linux清除用户登录记录和命令历史方法