Chinaunix首页 | 论坛 | 博客
  • 博客访问: 762235
  • 博文数量: 803
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 5015
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-28 10:29
文章分类

全部博文(803)

文章存档

2011年(1)

2008年(802)

我的朋友

分类:

2008-10-29 11:32:17


  摘要:和luster学习在Linux创建库函数
  3.4. 创建一个共享函数库
  
    现在我们开始学习如何创建一个共享函数库。其实创建一个共享函数库非常容易。首先创建object文件,这个文件将加入通过gcc –fPIC 参数命令加入到共享函数库里面。PIC的意思是“位置无关代码”(Position Independent Code)。下面是一个标准的格式:
  
  gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list
  
    下面再给一个例子,它创建两个object文件(a.o和b.o),然后创建一个包含a.o和b.o的共享函数库。例子中”-g”和“-Wall”参数不是必须的。
  
  gcc -fPIC -g -c -Wall a.cgcc -fPIC -g -c -Wall b.cgcc -shared -Wl,
  -soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o -lc
  
    下面是一些需要注意的地方:
  
  · 不用使用-fomit-frame-pointer这个编译参数除非你不得不这样。虽然使用了这个参数获得的函数库仍然可以使用,但是这使得调试程序几乎没有用,无法跟踪调试。 · 使用-fPIC来产生代码,而不是-fpic。 · 某些情况下,使用gcc 来生成object文件,需要使用“-Wl,-export-dynamic”这个选项参数。通常,动态函数库的符号表里面包含了这些动态的对象的符号。这个选项在创建ELF格式的文件时候,会将所有的符号加入到动态符号表中。可以参考ld的帮助获得更详细的说明。
    3.5. 安装和使用共享函数库
  
    一旦你了一个共享函数库,你还需要安装它。其实简单的方法就是拷贝你的库文件到指定的标准的目录(例如/usr/lib),然后运行ldconfig。
  
    如果你没有权限去做这件事情,例如你不能修改/usr/lib目录,那么你就只好通过修改你的环境变量来实现这些函数库的使用了。首先,你需要创建这些共享函数库;然后,设置一些必须得符号链接,特别是从soname到真正的函数库文件的符号链接,简单的方法就是运行ldconfig:
  
   ldconfig -n directory_with_shared_libraries
  
    然后你就可以设置你的LD_LIBRARY_PATH这个环境变量,它是一个以逗号分隔的路径的集合,这个可以用来指明共享函数库的搜索路径。例如,使用bash,就可以这样来启动一个程序my_program:
  
  LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH my_program
  
    如果你需要的是重载部分函数,则你就需要创建一个包含需要重载的函数的object文件,然后设置LD_PRELOAD环境变量。通常你可以很方便的升级你的函数库,如果某个API改变了,创建库的程序会改变soname。然而,如果一个函数升级了某个函数库而保持了原来的soname,你可以强行将老版本的函数库拷贝到某个位置,然后重新命名这个文件(例如使用原来的名字,然后后面加.orig后缀),然后创建一个小的“wrapper”脚本来设置这个库函数和相关的东西。例如下面的例子:
  
   #!/bin/sh export LD_LIBRARY_PATH=/usr/local/my_lib:$LD_LIBRARY_PATH exec
   /usr/bin/my_program.orig $*
  
    我们可以通过运行ldd来看某个程序使用的共享函数库。例如你可以看ls这个实用工具使用的函数库:
  
   ldd /bin/ls
   libtermcap.so.2 => /lib/libtermcap.so.2 (0x4001c000)
   libc.so.6 => /lib/libc.so.6 (0x40020000)
   /lib/ld-.so.2 => /lib/ld-.so.2 (0x40000000)
  
    通常我么可以看到一个soname的列表,包括路径。在所有的情况下,你都至少可以看到两个库:
  
  · /lib/ld-linux.so.N(N是1或者更大,一般至少2)。
  这是这个用力加载其他所有的共享库的库。
  · libc.so.N(N应该大于或者等于6)。这是C语言函数库。
  
    值得一提的是,不要在对你不信任的程序运行ldd命令。在ldd的manual里面写得很清楚,ldd是通过设置某些特殊的环境变量(例如,对于ELF对象,设置LD_TRACE_LOADED_OBJECTS),然后运行这个程序。这样就有可能使得某地程序可能使得ldd来执行某些意想不到的代码,而产生不的隐患。
  
  
  
【责编:admin】

--------------------next---------------------

阅读(341) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~