关于shared library的描述。

本文深入介绍了Linux系统中共享库的基本概念、创建方法及其使用技术。涵盖了共享库的命名规则、装载机制、动态加载函数等内容,并提供了创建和使用共享库的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以前搞共享库动态加载管理时找的一些资料,放在这里共享。

 

引言:
xmeeting中,usb手柄部分,采用动态库调用方式,下面翻一篇David A. Wheeler的文章。文章就如何建和使用态库,共享以及如何动态载库进行了述。要如下:
 1.

 2.
态库
 3.
共享
   3.1

       3.2
使用
    3.3

   3.4
建共享
   3.5
安装使用
   3.6
兼容性
 4.
动态
   4.1 dlopen()
   4.2 dlerror()
   4.3 dlsym()
   4.4 dlclose()
   4.5
示例
 5.
助知
   5.1 nm
命令
   5.2

   5.3
脚本
   5.4
版本
   5.5 GNU libtool
    5.6
去除符
   5.7
外部行体
    5.8 C++
C
   5.9
加速C++初始化

   5.10 Linux

1.

 
本文就如何在LinuxGNU工具建和使用程序库进述。所"程序"简单说,就是包含了据和的文件。其不能单独执行,可以作行程序的一部分,完成行功能。的存在,可以使得程序模化,可以加快程序的再编译,可以实现重用,可以使得程序便于升。程序可分三态库,共享动态载库

  态库,是在行程序行前就已加入到中,在物理上成为执行程序的一部分;共享,是在行程序动时行程序中,可以被多行程序共享使用。动态载库,其实并不是一种真正的库类型,应该是一种库的使用技用程序可以在程中和使用
 
议库开发员创建共享,比优势在于立的,便于维护和更新;而态库的更新比,一般不做推荐。然而,又各有点,后面到。在C++程中,要使用动态,需要考文章"C++ dlopen MINI-Howto"
 
文章中述的行程序和都采用ELF(Executable and Linking Format)格式,GNU GCC 工具可以理其格式,但不在本文的讨论。本文可以在 http://www.dwheeler.com/program-library http://www.linuxdoc.org 找到。

2.态库
 
态库可以认为是一些目的集合。按照习惯,一般以".a"文件后名。使用ar(archiver)命令可以态库。因共享有着更大的优势态库不被常使用。但态库使用简单,仍有使用的余地,并会一直存在。

  态库用程序生成,可以不必再编译省再编译时间。但在编译器越越快的今天,一点似乎已不重要。如果其他开发要使用的代,而又不想其源,提供态库是一种选择用程序使用了态库,要比使用动态载库速度快1-5%,但由于莫名的原因,实际上可能非如此。由此看,除了使用方便外,态库可能非一好的选择

  建一个静态库,或要加入到已存在的态库中,可以使用以下命令:
  ar rcs my_libraty.a file1.o file2.o
 
以上表示要把目标码file1.ofile2.o加入到态库my_library.a中。若my_library.a不存在,动创建。
 
 
态库创建成功后,需要接到用程序中使用。如果使用gcc(1)行程序,需要利用-l选项来指定态库。更多信息,gcc使用手

  在使用gcc,要注意其参数序。-l接器选项,一定要放在被编译的文件名之后;若放在文件名之前,你会接失并会莫名其妙的错误一点切
 
 
也可以直接使用接器ld(1),使用其选项-l-L。但最好使用gcc(1),ld(1)的接口有可能化。

3.共享
 
共享是在程序动时被装用程序装了一共享后,其用程序仍可以装同一共享。基于linux的使用方法,共享库还有其它灵活的而又精妙的特性:
  
更新库并不影用程序使用的,非向后兼容的版本;
  
行特定程序,可以覆盖整或更新中的特定函
  
以上操作不经运行的程序,他使用已

3.1
  
要想共享具有以上特性,一些定需要遵守。需要掌握共享,特是搜名(soname)(realname)系;需要知道共享在文件系的位置。
3.1.1

 
共享都有一特定的搜名(soname),成如下:
  lib  + 
  +  .so  +  .  +  version
   |       |        |_______________|
 
               

 
在文件系中,搜名是一指向名的符联结

  共享也有一名,其正包含有的代成如下:
 
搜名 +  .   +  子版本 + . +
 
最后的句点和是可选项
 
 
另外,共享库还有一,一般用于编译连接,为连(linker name)可以被看作是有任何版本的搜名。
    

  看下面的例子:
  lrwxrwxrwx  1 root root  libpng.so -> libpng12.so
  lrwxrwxrwx  1 root root  libpng.so.2 ->   libpng.so.2.1.0.12
  -rw-r--r--  1 root root  libpng.so.2.1.0.12
 
在以上信息中,  libpng.so.2.1.0.12是共享(real name)libpng.so.2是共享搜名(soname),libpng.so 接名(linker name),用于编译连接。

3.2共享的装
 
在所有基于GNU glibc的系(然包括Linux)中,在ELF行程序,一特殊的程序"程序装"被自载并运行。在linux中,这个程序装器就是/lib/ld-linux.so.X(X是版本)它会载应用程序所依的所有共享
 
被搜索的目保存在/etc/ls.so.conf文件中,但一般/usr/local/lib不在搜索之列,至少debian这样似乎是一,只好自己加上了。
 
然,如果程序的每次,都要去搜索一番,必效率不堪忍受。Linux虑这一点,共享采用了存管理。ldconfig就是实现这一功能的工具,其缺省/etc/ld.so.conf文件,所有共享按照一定范建立符接,然后信息/etc/ld.so.cache /etc/ld.so.cache的存在大大加快了程序的速度。

3.3建共享
 
共享建比较简单,基本有步。首先使用-fPIC-fpic建目文件,PICpic表示位置无,然后就可以使用以下格式建共享了:
 gcc -share _Wl,-soname,your_soname -o library_name file_list library_list
 
下面是使用a.cb.c的示例:
   gcc -fPIC -g -c -Wall a.c
   gcc -fPIC -g -c -Wall b.c
   gcc -share -Wl,-soname, libmyab.so.1 -o libmyab.so.1.0.1 a.o b.o -lc
   -g
表示调试信息,-Wall表示生警告信息。
 
需要注意的地方:
  (1)
不推荐使用strip理共享,最好不要使用-fomit-frame-pointer编译选项
  (2)-fPIC
-fpic都可以生目标独立代,一般采用-fPIC管其生的目文件可能大些;-fpic生的代小,行速度快,但可能有平台依限制。
  (3)
一般情下,-Wall,-soname,your_soname编译选项是需要的。然,-share选项更不能

4 动态载库
  DL
可以允许应用程序在程的任何候去加和使用指定的一技件的实现上很用。CJP, alarm ui 使用插件技术。对于这里边的体会还是有一点的。最大的体会就是,要好好利用dlerror(), 如果早使用dlerror(),则不会浪费这么多的时间在编译修改plugin库上面。)动态载库这不是着眼于的文件格式,而是指使用方式。存在着一接口函,使得用程序可以采用DL。下面对这些接口函逐一介,在最后用示例。

4.1 dlopen
 
原型:
void *dlopen(const char *libname,int flag);
 
功能描述:dlopendlerrordlsymdlclose之前用,表示要存,准使用。如果要装于其,必首先装赖库。如果dlopen操作失,返回NULL;如果被装载过dlopen返回同的句柄。

 
参数中的libname一般是的全路这样dlopen直接装载该文件;如果只是指定了,在dlopen按照下面的机制去搜
  (1)
根据LD_LIBRARY_PATH
  (2)
根据/etc/ld.so.cache
  (3)
找依次在/lib/usr/lib录查找。
  flag
参数表示理未定的方式,可以使用RTLD_LAZYRTLD_NOWRTLD_LAZY表示暂时不去理未定,先把存,等用到的函RTLD_NOW表示检查是否存在未定的函,若存在,dlopen以失cjp, 如果出错返回了,则可以调用dlerror()查看到具体的原因,这个是非常重要的。

4.2 dlerror
 
原型:
char *dlerror(void);
 
功能描述:dlerror可以最近一次dlopen,dlsymdlclose操作的错误信息,返回NULL表示无错误dlerror在返回错误信息的同,也会清错误信息。

4.3 dlsym
 
原型:
void *dlsym(void *handle,const char *symbol);
 
功能描述:在dlopen之后,被装存。dlsym可以得指定函(symbol)存中的位置()。如果找不到指定函dlsym返回NULL。但判是否存在最好的方法是使用dlerror,下面是示例:

  dlerror();/*
错误信息*/
  function = dlsym(handle,"function_name");
  if((error=dlerror()) != NULL)
  {
    /*
错误处
*/
  }
  else
  {
    /*
找到函
*/
  }

4.4 dlclose
 
原型:
int dlclose(void *);
 
功能描述:句柄一,如果句柄至零,则该库会被卸。如果存在析dlclose之后,析数会用。

4.5动态载库示例
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main(int argc,char **argv)
{
  void *handle;
  double (*cosine)(double);
  char *error;

  handle = dlopen("/lib/libm.so.6",RTLD_LAZY);
  if(!handle)
  {
    printf("%s/n",dlerror());
    exit(1);
  }

  printf("opened /lib/libm.so.6/n");

  cosine = dlsym(handle,"cos");
  if((error = dlerror()) != NULL)
  {
    printf("%s/n",error);
    dlclose(handle);
    printf("after error,closed /lib/libm.so.6/n");
    exit(1);
  }

  printf("%f/n",(*cosine)(2.0));

  dlclose(handle);
  printf("closed /lib/libm.so.6/n");

  return 0;
}
 
编译gcc -o test test.c -ldl。在这个例子中,/lib/libm.so.6动态载库,而/usr/lib/libdl.so是共享


5.

5.1 nm
命令
  nm(1)
命令可以的符列表,的相信息是一的工具。具体使用助文。示例:
nm -D libavcodec-0.4.7.so | grep 263
果如下:

00109d40 T h263_encode_mb
00105f94 T h263_encode_picture_header
001a85a0 D h263_encoder
001162d0 T h263_get_picture_format
0010a7b4 T h263_pred_motion
00106df8 T h263_send_video_packet
001ab180 D h263i_decoder
001a85e0 D h263p_encoder
00115c68 T intel_h263_decode_picture_header
……………
其中,T表示正常代D表示初始化据段

5.2
 
,一般不需要自己去实现。如果一定要自己做,下面是函原型:
  void __attribute__ ((constructor)) my_init(void);
  void __attribute__ ((destructor)) my_fini(void);
 
编译共享库时,不能使用"-nonstartfiles""-nostdlib"选项,否数将不能正常(除非采取一定措施)

5.3脚本共享
  linux
,共享可以是脚本形式,然需要专门的脚本言。/usr/lib/libc.so是一典型的例子,容如下:
  /* GNU ld script
     Use the shared library, but some functions are only in
     the static library, so try that secondarily.  */
  OUTPUT_FORMAT(elf32-i386)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )

5.4 版本脚本()
5.5 GNU libtool(
)

5.6除去记号信息
 
共享中的记号信息多为调试之用,但占用了磁。如果嵌入式系所用,最好去掉记号信息。一方法,利用strip(1)命令,使用方法看其助文;另一方法,使用GNU LD选项-s-S,例如"-Wl -s""-Wl -S"-S除去调试记号信息;-s除去所有记号信息。

5.7编译优
 
有一篇文章的不"Whirlwind tutorial On Creating really teensy ELF Executables For Linux"篇文章中可以把程序的代码优化到了点。在我们实际用中,可能需要那些技巧,但通此文,我可以更多的了解ELF

5.8 C++C
 
要使得编写的共享能同CC++程序使用,文件需要使用"extern C",下面是一例子:

  #ifndef LIB_HELLO_H
  #define LIB_HELLO_H

  #ifdef __cplusplus
  extern "C"
  {
  #endif

  .....文件代
 
  #ifdef __cplusplus
  }
  #endif

  #endif

5.9C++程序的速度
  C++
用程序的速度是比慢的。我一直使用firefox,感受深。有人认为这是因主函数启之前的代重定位所致。有一篇文章"making C++ ready for the desktop"(by Waldo Bastian)对这问题作了分析。我了一下,理解不是很深刻。

5.10 Linux Standard Base(LSB)
  LSB
是一目,致力于制和推一系列准,力提高不同Linux布版本之的兼容性,为应用程序的开发提供一致性的接口。linux目的详细信息,可查阅网www.linuxbase.org




 

Trackback: http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1510037

 

 

 

 

 linux 建共享.so

类似Windows系统中的动态链接库,Linux中也有相应的共享库用以支持代码的复用。Windows中为*.dll,而Linux中为*.so,我来详细的告诉你如何在linux下编写动态库,以及如何使用它.

linux下编写动态链接库的步骤:

 

1.      编写库的头文件和源文件.

2.      把所有涉及到的源文件用如下方式编译为目标文件:

 

g++/gcc -g -c -fPIC -o library1.o library1.cpp

g++/gcc -g -c -fPIC -o library2.o library2.cpp
      ......

......

(注释:-fPIC指通过这个选项来生成与位置无关的代码,可以在任何地址被连接和装载,-c指只编译而不连接原程序)

 

3.      把所有的目标文件链接为动态库:

 

g++/gcc -g -shared -Wl,-soname,lib***.so -o lib***.so.1.0.0 library1.o library2.o ....  -lc

                

    (注释:-lc选项,表示使用c语言库,一般都要用到)

 

4.      建立一个库名链接

 

ln -s lib***.so.1.0.0 lib***.so

 

现在你就可以引用库了.下面我分别给出简单例子告诉你如何动态和静态使用动态库:

假如你的应用程序源代码叫testlib.cpp

采用/如下方式编译:

 

      g++ -g -o testlib testlib.cpp -ldl

            

    (注释:-ldl选项,表示生成的对象模块需要使用共享库)

 

////////这个例子告诉你如何动态的调用.so

testlib.cpp

#include <dlfcn.h>

#include <iostream.h>

#include ...

int main()

{

       void *handle=NULL;

       //define a pointer which will point to the function in the lib you want to use.

       YourFuntionType (*pFunc)(YourFunctionPerameterList........);

       //open the lib you want to use.

       handle=dlopen("/../../../yourlib.so",RTLD_LAZY);

       if(handle==NULL)

       {

              cout<<"failed loading library!"<<endl;

              return -1;

       }

       dlerror();

       //try to load the function in lib

       pFunc=(YourFuntionType(*)(YourFunctionPerameterList))dlsym(handle,"YourFuntionName");

       if(dlerror()!=NULL)

       {

              cout<<"Loading function in lib error!"<<endl;

              return -1;

       }

       //now you can use the funtion like this

       (*pFunc)(YourFuntionPerameterList);

       return 0;

}  

 

(注释:dlopen()

              第一个参数:指定共享库的名称,将会在下面位置查找指定的共享库。

-环境变量LD_LIBRARY_PATH列出的用分号间隔的所有目录。

-文件/etc/ld.so.cache中找到的库的列表,用ldconfig维护。

-目录usr/lib

-目录/lib

-当前目录。(这里就是这种情况)

 

第二个参数:指定如何打开共享库。

RTLD_NOW:将共享库中的所有函数加载到内存

RTLD_LAZY             会推后共享库中的函数的加载操作,直到调用dlsym()时方加载某函数

dlsym()

          调用dlsym时,利用dlopen()返回的共享库的phandle以及函数名称作为参数,返回要加载函数的入口地址。

       dlerror()

    该函数用于检查调用共享库的相关函数出现的错误。

 

特别需要注意的几点问题:

1.      当你想用c++写动态库的时候,记住千万别忘了在头文件里面加上如下内容,否则生成的库在动态调用的时候会出问题!!!!!!!

 #ifdef __cplusplus
       extern "C" {

#endif

....

....

   #ifdef __cplusplus

}

#endif 

 

2.      当你的库中包括与omniORB3相关的东西的时候,一定要在makefile中加上 -D__x86__ -D__OSVERSION=4

 

/////////////这个例子告诉你如何静态调用.so

首先你得确保你的应用程序能够找到你的.so,这可以有几种方法来实现.

方法一:

1.你可以把YourLib.so.1.0.0 YourLib.so放到/usr/lib,然后执行命令:ldconfig,这样你就可以在你的应用程序中直接调用你库中的函数了,当然你 得把库的头文件包含到你的应用程序中

2.编译你的应用程序

g++/gcc -g -o yourapp yourapp.cpp –lYourLib

 

方法二:

1.你也可以采用在系统中设置环境变量的办法来实现root目录下:

vi .bash_profile

然后添加LD_LIBRARY=/../YourDirIncludingYourLib

然后注消一次,环境变量就生效了,这样你就可以在你的应用程序中直接调用库中的函数了,同样你得有头文件.

2.编译你的应用程序

g++/gcc -g -o yourapp yourapp.cpp –lYourLib

 

方法三:

你可以直接采用在编译链接的时候告诉系统你的库在什么地方
       g++/gcc -g -o yourapp yourapp.cpp -L/YourDirIncludingYourLib –lYourLib

/////////////////////////////////

假如你的库中有个函数:int eat(.....)

那么采用如下方式调用它

yourapp.cpp

#include "YourLib.h"

int main()

{

       eat();

return 0;

}

 

是不是很easy?对了在静态调用的时候好像不存在上面的"注意1"的问题,不过鉴于保险起见,最好还是按照标准的方式写c++头文件吧,这绝对是个好习惯.

 

 

 

 

 

 

 

 

.的分
   
种说法,如果熟悉WIN平台下的DLL,相信不理解:

    可以有三使用的形式:、共享和动态态库的代编译时就已接到开发员开发用程序中,而共享只是在程序入,在编译时,只是简单地指定需要使用的动态库则是共享的另一种变化形式。动态库也是在程序时载入,但共享不同的是,使用的不是在程序始,而是在程序中的句需要使用入。动态库可以在程序行期间释动态库所占用的存,出空供其程序使用。由于共享动态库并没有在程序中包括容,只是包含了对库的引用,因此代模比小。

    Linux下的文件分共享态库两们两者的差别仅在程序所需的代是在时动态的,是在编译时静态的。库类型最好的方法是看的文件后,通常共享.so(Shared Object缩写)尾,态链通常以.a(Archive缩写)。在端缺省情下,共享通常为绿色,而态库为黑色。


 
经开发的大多都采取共享的方式。ELF格式的可行文件使得共享容易地实现然使用a.out模式也可以实现库的共享。Linux中目前可行文件的格式ELF格式。

  .a的是了支持老的a.out格式的可行文件的
  .so的是支持elf格式的可行文件的

   .a态库文件,可以用ar 命令生成。
  .so动态库文件,编译时加上指定的选项即可生成,具体选项看相的系了。


.的命名规则
    GNU
的使用必遵守Library GNU Public License(LGPL协议)该协议与GNU协议略有不同,开发可以免使用GNU库进开发,但必向用提供所用的的源代

  系中可用的都存放在/usr/lib/lib中。文件名由前lib名以及后缀组成。根据型不同,后名也不一。共享的后名由.so和版本成,态库的后.a。采用a.out格式的共享的后.sa
  
libname.so.major.minor
  libname.a

  里的name可以是任何字符串,用唯一标识字符串可以是一字、几字符、甚至一字母。数学共享libm.so.5里的标识字符m,版本5libm.a数学X-WindowslibX11.so.6里使用X11为库标识,版本6

三。操作命令

   Linux操作可以使用命令完成,目前常用的命令是lddldconfig

   1.ldd
 ldd
Library Dependency Display缩写的作用是示一行程序使用的共享

 $ ldd /usr/bin/mesg
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eaf000)
 /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7feb000)

   2.ldconfig
 
安装到系以后,让动态链库为认识及共享,就需要ldconfigldconfig命令的用途,主要是在默(/lib/usr/lib)以及动态库配置文件/etc/ld.so.conf所列的目下,搜索出可共享的动态链(格式如lib*.so*)建出动态装入程序(ld.so)所需的接和存文件。存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链名字列表,ldconfig通常在系统启动时运行,而安装了一新的动态链库时,就需要手工这个命令。

     1)命令格式
 ldconfig [
选项] [libs]

     2)主要选项
 -v
--verbose ldconfig示正在描的目、搜索到的动态链,以及建的接的名字。

 -f CONF 指定动态链的配置文件CONF,系认为/etc/ld.so.conf

 -C CACHE 指定生成的存文件CACHE,系的是/etc/ld.so.cache,文件存放已排好序的可共享的动态链的列表。

 -p--print-cache ldconfig打印出存文件所保存的所有共享的名字。

 -r ROOT 变应用程序的根目录为ROOT

 n ldconfig仅扫描命令行指定的目,不描默(/lib/usr/lib),也不描配置文件/etc/ld.so.conf所列的目

 选项ldconfig命令,用于更新高速冲文件。这个命令主要用于高速DNS(Caching DNS Server)。高速DNS器的原理是提供查询记录且利用记录来提高查询的效率。

 查询是第一次被送到高速DNS,高速DNS器就查询的整记录,在一定的它来回答所有相同的查询少整DNS且提高查询速度。

四。的升

 Linux统软件更新很快,新的核心几乎每几星期就公布一次,其件的更新也是非常繁。多下,盲目跟潮流的升级并不必要,如果确需要新版本的特性再升话说,不要而升Linux中多件都是用共享库来编译的,其中包含了在不同程序之共享的公用子例程。

行某程序,如果看到如下信息:“Incompatible library version表明需要该库到程序所需要的版本。是向下兼容的,也就是,用老版本库编译的程序可以在新安装的版本行,反之不行。

Linux的升是一重要的工作,往往件包的升有一定关联作用,所以操作前一定要备份文件。下面看一下如何把Glibc 2.2.4.132.3.2版本,其程如下:

  1..gz压缩文件

GUN C站下的四.gz压缩文件,解至一临时:
cd /usr/caolinux
tar xzvf glibc-2.3.2.tar.gz
cd glibc-2.3.2
tar xzvf ../glibc-linuxthreads-2.3.2.tar.gz
tar xzvf ../glibc-crypt-2.3.2.tar.gz
tar xzvf ../glibc-localedata-2.3.2.tar.gz

  2.建立的安装目
mkdir /usr/higlibc
cd /usr/higlibc

   3.建立编译
mkdir cao
cd cao
./configure --enable-add-ons=linuxthreads,crypt,localedata -prefix=/usr/higlibc

  4.编译与安装
make
make check
make install

  5.变数
ln -s /usr/higlibc/lib/ld-linux.so.2 /lib/ld-linux.so.2

然后,修改/etc/ld.so.conf,加入一行/usr/higlibc/lib行下面代
ldconfig -v

更新/etc/ld.so.cache容,列出每的版本描目和所要建及更新的接。

 6.更改GCC

cd /usr/lib/gcc-lib
cp -r i386-redhat-linux higlibc

 7.更新符
cd /usr/higlibc/include
ln -s /usr/src/linux/include/linux
ln -s /usr/src/linux/include/asm
ln -s /usr/X11R6/include/X11

8.测试并完成

五。高共享特性
 1. soname

共享的一非常重要的,也是非常念是 soname——简写共享目名(short for shared object name)。是一共享.so)文件而嵌在控制据中的名字。如前面提到的,每一程序都有一需要使用的这个清单容是一系列 soname,如同 ldd 示的那,共享器必找到这个清单

soname 关键功能是提供了兼容性的准。要升中的一库时且新 soname 和老的 soname ,用库连接生成的程序,使用新的依然能正常行。这个特性使得在 Linux 下,升使用共享的程序和定位错误变得十分容易。

Linux 中,用程序通使用 soname指定所希望的版本。作者也可以通保留或者改 soname 来声明,些版本是相互兼容的,使得程序员摆脱了共享版本冲突问题的困

/usr/local/lib ,分析 MiniGUI 的共享文件之

2. 共享

程序被用的候,Linux 共享器(也被为动态连接器)也自用。的作用是保程序所需要的所有适版本的都被存。共享器名字是 ld.so 或者是 ld-linux.so Linux libc 的版本,使用一点外部交互,才能完成自己的工作。然而接受在量和配置文件中的配置信息。

文件 /etc/ld.so.conf 准系统库的路。共享器把搜索路了改变这个设置,必 root 份运 ldconfig 工具。这将更新 /etc/ls.so.cache 文件,这个文件其是装部使用的文件之一。

3. 使用 dlopen

另外一强大的 dlopen()数将装入存。主要用载库中的符些符编译候是不知道的。比如 Apache Web 器利用这个程中加这为它提供了外的能力。一配置文件控制了加程。这种机制使得在系中添加或者除一块时,都不需要重新编译了。

可以在自己的程序中使用 dlopen()dlopen() dlfcn.h 中定 dl 实现需要两个参数:一文件名和一志。文件名可以是我们学习过中的 soname志指明是否立刻的依性。如果 RTLD_NOW 立刻算;如果置的是 RTLD_LAZY在需要的候才算。另外,可以指定 RTLD_GLOBAL使得那些在以后才加可以得其中的符

被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以得符中的地址。使用这个地址,就可以中特定函的指用装载库中的相

六、LINUX动态链的使用
重要的dlfcn.h文件

LINUX
下使用动态链,源程序需要包含dlfcn.h文件,此文件定动态链的函的原型。下面详细说明一下些函

1
dlerror
原型
: const char *dlerror(void);
动态链操作函行失败时dlerror可以返回出信息,返回值为NULL表示操作函行成功。

2
dlopen
原型
: void *dlopen (const char *filename, int flag);
dlopen
用于打指定名字(filename)动态链返回操作句柄。

filename:
如果名字不以/开头绝对名,按下列先后文件。

(1)
户环量中的LD_LIBRARY

(2)
动态链冲文件
/etc/ld.so.cache
(3)
/lib
/usr/lib
flag
表示在什么时候解未定的符()。取两个
:
1) RTLD_LAZY :
表明在动态链的函码执

2) RTLD_NOW :
表明在dlopen返回前就解所有未定的符,一旦未解dlopen返回错误

dlopen
用失败时返回NULL,否返回的是操作句柄。

3
dlsym : 取函行地址

原型
: void *dlsym(void *handle, char *symbol);
dlsym
根据动态链操作句柄(handle)(symbol),返回符对应的函行代地址。由此地址,可以带参数执行相的函

如程序代: void (*add)(int x,int y); /* 明一下要用的动态
add */
add=dlsym("xxx.so","add"); /*
xxx.so共享,add地址
*/
add(89,369); /*
带两个参数89369add
*/
4
dlclose : 关闭动态链

原型
: int dlclose (void *handle);
dlclose
用于关闭指定句柄的动态链,只有动态链的使用计数为0,会真正被系

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值