dlopen linux_linux dlopen - CSDN
  • linuxdlopen的使用

    2012-12-12 18:07:03
    dlopen()  功能:打开一个动态链接库  包含头文件:  #include  函数定义:  void * dlopen( const char * pathname, int mode );    函数描述:  在dlopen的()函数以...
    
    


    dlopen()

      功能:打开一个动态链接库

      包含头文件:

      #include <dlfcn.h>

      函数定义

      void * dlopen( const char * pathname, int mode );

     

      函数描述:

      在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。

     

     mode是打开方式,其值有多个,不同操作系统上实现的功能有所不同,在linux下,按功能可分为三类:       

            1、解析方式

             RTLD_LAZY:在dlopen返回前,对于动态库中的未定义的符号不执行解析(只对函数引用有效,对于变量引用总是立即解析)。
            RTLD_NOW: 需要在dlopen返回前,解析出所有未定义符号,如果解析不出来,在dlopen会返回NULL,错误为:: undefined symbol: xxxx.......

            2、作用范围,可与解析方式通过“|”组合使用。 
            RTLD_GLOBAL:动态库中定义的符号可被其后打开的其它库重定位。 
            RTLD_LOCAL: 与RTLD_GLOBAL作用相反,动态库中定义的符号不能被其后打开的其它库重定位。如果没有指明是RTLD_GLOBAL还是RTLD_LOCAL,则缺省为RTLD_LOCAL。

            3、作用方式

            RTLD_NODELETE: 在dlclose()期间不卸载库,并且在以后使用dlopen()重新加载库时不初始化库中的静态变量。这个flag不是POSIX-2001标准。 
            RTLD_NOLOAD: 不加载库。可用于测试库是否已加载(dlopen()返回NULL说明未加载,否则说明已加载),也可用于改变已加载库的flag,如:先前加载库的flag为RTLD_LOCAL,用dlopen(RTLD_NOLOAD|RTLD_GLOBAL)后flag将变成RTLD_GLOBAL。这个flag不是POSIX-2001标准。
            RTLD_DEEPBIND:在搜索全局符号前先搜索库内的符号,避免同名符号的冲突。这个flag不是POSIX-2001标准。

     

      返回值:

      打开错误返回NULL

      成功,返回库引用

      编译时候要加入 -ldl (指定dl)

      例如

      gcc test.c -o test -ldl

    展开全文
  • 一、引言  通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。...

     一、引言

             通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“libxxx.a”的形式。

             其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是动态链接库(dynamic link library)技术。


             二、动态链接库的特点与优势

            首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

            1. 可以实现进程之间的资源共享。

            什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

            2. 将一些程序升级变得简单。

            用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

     

           3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

            程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。


            三、动态链接库的创建

             由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position IndependentCode (PIC))。

            对gcc编译器,只需添加上-fPIC 标签,如:

            gcc -fPIC -c file1.c
            gcc -fPIC -c file2.c
            gcc -shared -o libxxx.so    file1.o file2.o


            也可以直接生成.so:

             gcc -fPIC -shared -o libxxx.so    file1.c file2.c


          注意到最后一行,-shared标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”


            3.1 编译参数解析

            最主要的是GCC命令行的一个选项: -shared  。 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

           -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

          -L.:表示要连接的库在当前目录中

          -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

          LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

           当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

          3.2 注意

          调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

     

      四、LINUX下动态链接库的使用

      4.1 重要的dlfcn.h头文件

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

      4.1.1 dlerror

      原型为: const char *dlerror(void);

      当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。


      4.1.2 dlopen

      原型为: void *dlopen (const char *filename, intflag);

      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值,否则返回的是操作句柄。


      4.1.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); /* 带两个参数89和369调用add函数 */

      

           4.1.4 dlclose : 关闭动态链接库

      原型为: int dlclose (void *handle);

      dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。


      4.2 在程序中使用动态链接库函数

      4.2.1 程序范例

      下面的程序装载了动态链接库my.so,并用getdate,gettime取得当前日期与时间后输出。

      ----------------------------------------------------------------------

      1 /************************************/

      2 /* 文件名称: dy.c */

      3 /* 功能描述: 动态链接库应用示范程序 */

      6 /************************************/

      7

      8 #include "stdio.h" /* 包含标准输入输出文件 */

      9

      10 #include "dlfcn.h" /* 包含动态链接功能接口文件 */

      11 #define SOFILE "./my.so" /* 指定动态链接库名称 */

      12

      13 #define SHARED /* 定义宏,确认共享,以便引用动态函数 */

      14 #include "datetime.h" /* 包含用户接口文件 */

      15

      16 main()

      17 {

      18 DATETYPE d;

      19 TIMETYPE t;

      20 void *dp;

      21 char *error;

      22

      23 puts("动态链接库应用示范");

      24

      25 dp=dlopen(SOFILE,RTLD_LAZY); /* 打开动态链接库 */

      26

      27 if (dp==NULL) /* 若打开失败则退出 */

      28 {

      29 fputs(dlerror(),stderr);

      30 exit(1);

      31 }

      32

      33 getdate=dlsym(dp,"getdate"); /*定位取日期函数 */

      34

      35 error=dlerror(); /* 检测错误 */

      36 if (error) /* 若出错则退出 */

      37 {

      38 fputs(error,stderr);

      39 exit(1);

      40 }

      41

      42 getdate(&d); /* 调用此共享函数 */

      43 printf("当前日期:%04d-%02d-%02d\n",d.year,d.mon,d.day);

      44

      45 gettime=dlsym(dp,"gettime"); /*定位取时间函数 */

      46

      47 error=dlerror(); /* 检测错误 */

      48 if (error) /* 若出错则退出 */

      49 {

      50 fputs(error,stderr);

      51 exit(1);

      52 }

      53

      54 gettime(&t); /* 调用此共享函数 */

      55 printf("当前时间:%02d:%02d:%02d\n",t.hour,t.min,t.sec);

      56

      57 dlclose(dp); /* 关闭共享库 */

      58

      59 exit(0); /* 成功返回*/

      60

      61 }

      ----------------------------------------------------------------------

    程序说明:

      第8行: 包含标准输入输出头文件,因为程序中使用了printf,puts,fputs等标准输入输出函数,需要让编译器根据头文件中函数的原型,检查一下语法;

      第10-11行: 包含动态链接库功能头文件,并定义动态链接库名称;

      第13-14行: 定义宏SHARED以便引用14行的头文件datetime.h中的动态函数说明;

      第25行: 用dlopen打开SOFILE共享库,返回句柄dp;

      第27-31行: 检测dp是否为空,为空则显示错误后退出;

      第33行: 用dlsym取得getdate函数动态地址;

      第35-40行: 如果dlerror返回值不为空,则dlsym执行出错,程序显示错误后退出;

      第42-43行: 执行getdate调用,输出当前日期;

      第45行: 用dlsym取得gettime函数动态地址;

      第47-52行: 如果dlerror返回值不为空,则dlsym执行出错,程序显示错误后退出;

      第54-55行: 执行gettime调用,输出当前时间;

      第57行: 用dlclose关闭dp所指示的动态链接库;

      第59行: 程序退出,返回0值。

      

    2.2.2 编写维护文件

      维护文件makefile内容如下:

      ----------------------------------------------------------------------

      1 # makefile :

      2

      3 all : dy

      4

      5 DYSRC = dy.c

      6

      7 DYTGT = $(DYSRC:.c=.o)

      8

      9 %.o : %.c

      10 cc -c $?

      11

      12 # 动态库应用示范程序

      13 dy : $(DYTGT)

      14 cc -rdynamic -s -o $@ $(DYTGT) -ldl

      15

      ----------------------------------------------------------------------

      维护文件说明:

      第3行: 定义所有需要维护的模块;

      第5行: 定义源程序;

      第7行: 定义目标文件;

      第9-10行: 定义.o文件依赖于.c文件,维护代码为“cc -c 变动的源文件名”;

      第13-14行: 定义dy依赖于变量DYTGT指示的值,维护代码中采用-rdynamic选项以指定输出文件为动态链接的方式,选项-s指定删除目标文件中的符号表,最后的选项-ldl则指示装配程序ld需要装载dl函数库。


      4.2.3 运行make命令

      运行make后将产生执行文件dy,运行后将产生如下类似信息:

      动态链接库应用示范

      当前日期: 2012-12-27

      当前时间: 21:10:30

      当删除my.so文件时,将出现以下信息:

      动态链接库应用示范

      my.so: cannot open shared object file: 文件或目录不存在


      五、小结

      LINUX创建与使用动态链接库并不是一件难事。

      编译函数源程序时选用-shared选项即可创建动态链接库,注意应以.so后缀命名,最好放到公用库目录(如/lib,/usr/lib等)下面,并要写好用户接口文件,以便其它用户共享。

      使用动态链接库,源程序中要包含dlfcn.h头文件,写程序时注意dlopen等函数的正确调用,编译时要采用-rdynamic选项与-ldl选项,以产生可调用动态链接库的执行代码。

    展开全文
  • linux dlopen 相关

    2018-08-25 14:20:31
    dlopen(3) - Linux手册页 名称 dladdr,dlclose,dlerror,dlopen,dlsym,dlvsym - 动态链接加载器的编程接口 概要 #include &lt; dlfcn.h &gt; void * dlopen(const char * filename ,int ...

    dlopen(3) - Linux手册页

    名称

    dladdr,dlclose,dlerror,dlopen,dlsym,dlvsym - 动态链接加载器的编程接口

    概要

    #include < dlfcn.h >

    void * dlopen(const char * filename ,int flag );

    char * dlerror(void);

    void * dlsym(void * handle ,const char * symbol );

    int dlclose(void * handle );

    -ldl链接。

    描述

    四个函数dlopen(),dlsym(),dlclose(),dlerror()实现了动态链接加载器的接口。

    dlerror获得()

    函数dlerror()返回一个人类可读的字符串,描述自从上次调用dlerror()以来dlopen(),dlsym()或 dlclose()发生的最新错误。如果从初始化或上次调用以来没有发生错误,它将返回NULL。

    dlopen的()

    函数dlopen()加载由以null结尾的字符串文件名命名的动态库文件,并为动态库返回一个不透明的“句柄”。如果文件名为NULL,则返回的句柄用于主程序。如果filename包含一个斜线(“/”),则它被解释为(相对或绝对)路径名。否则,动态链接器将按如下方式搜索库(有关更多详细信息,请参阅ld.so(8)):

    Ø

    (仅限ELF)如果调用程序的可执行文件包含DT_RPATH标记,并且不包含DT_RUNPATH标记,则搜索DT_RPATH标记中列出的目录。

    Ø

    如果在程序启动时,环境变量LD_LIBRARY_PATH被定义为包含冒号分隔的目录列表,则会搜索这些目录。(作为一个安全措施,这个变量在set-user-ID和set-group-ID程序中被忽略。)

    Ø

    (仅限ELF)如果调用程序的可执行文件包含DT_RUNPATH标记,则搜索该标记中列出的目录。

    Ø

    将检查缓存文件/etc/ld.so.cache(由ldconfig(8)维护)以查看它是否包含文件名条目。

    Ø

    搜索目录/ lib/ usr / lib按此顺序)。

    如果库对其他共享库有依赖关系,那么它们也会由动态链接程序使用相同的规则自动加载。(这个过程可能会递归发生,如果这些库依次具有依赖性,依此类推。)

    标志中必须包含以下两个值之一:

    RTLD_LAZY执行延迟绑定。只有在执行引用它们的代码时才解析符号。如果符号从未被引用,那么它永远不会被解析。(懒惰绑定仅针对函数引用执行;对于变量的引用总是在加载该库时立即绑定。)RTLD_NOW如果指定了该值,或者环境变量LD_BIND_NOW设置为非空字符串,则在dlopen()返回之前解析库中的所有未定义符号。如果无法完成,则返回错误。以下值中的零个或多个值也可以在标志中进行或运算:RTLD_GLOBAL由该库定义的符号将可用于随后加载的库的符号解析。RTLD_LOCAL这是RTLD_GLOBAL的反过来,如果既没有指定标志,也是默认值。此库中定义的符号不可用于解决随后加载的库中的引用。RTLD_NODELETE(自glibc 2.2以来)在dlclose()期间不要卸载该库。因此,如果库稍后用dlopen()重新加载,则库的静态变量不会重新初始化 。该标志在POSIX.1-2001中未被指定。RTLD_NOLOAD(自glibc 2.2以来)不要加载库。这可以用来测试库是否已经驻留(dlopen()如果不是,则返回NULL,如果库驻留则返回库)。该标志也可用于提升已加载库的标志。例如,以前加载RTLD_LOCAL的库 可以使用RTLD_NOLOAD |重新打开 RTLD_GLOBAL。该标志在POSIX.1-2001中未被指定。RTLD_DEEPBIND(自glibc 2.3.4开始)将该库中符号的查找范围放在全局范围之前。这意味着一个独立的库将使用它自己的符号而不是全局符号,这些符号包含在已经加载的库中。该标志在POSIX.1-2001中未被指定。如果filename是一个NULL指针,那么返回的句柄就是主程序。当提供给dlsym()时,该句柄将导致在主程序中搜索一个符号,然后在程序启动时加载所有共享库,然后使用dlopen()加载标志为 RTLD_GLOBAL的所有共享库。

    库中的外部引用通过使用该库的依赖项列表中的库以及之前使用RTLD_GLOBAL标志打开的其他库来解决 。如果可执行文件与标志“-rdynamic”(或同义词,“--export-dynamic”)链接,则可执行文件中的全局符号也将用于解析动态加载的库中的引用。

    如果使用dlopen()再次加载相同的库,则会返回相同的文件句柄。dl库维护库句柄的引用计数,因此动态库不会被释放,直到dlclose()被调用多次,直到dlopen()成功完成为止。在_init()例程,如果存在的话,只调用一次。但随后使用RTLD_NOW调用可能会强制使用先前加载RTLD_LAZY的库的符号解析 。

    如果dlopen()因任何原因失败,则返回NULL。

    对dlsym()

    函数dlsym()采用由dlopen()返回的动态库的“句柄” 和空终止的符号名称,并返回该符号加载到内存中的地址。如果未找到符号,则在指定库或dlopen()加载该库时自动加载的任何 库中,dlsym()返回NULL。(由dlsym()执行的搜索首先通过这些库的依赖树宽度)。由于符号的值实际上可以是NULL(所以dlsym()的NULL返回不需要指示错误),所以正确的方法测试错误是调用dlerror()清除任何旧的错误条件,然后调用dlsym(),然后再次调用dlerror(),将其返回值保存到变量中,并检查此保存的值是否不为NULL。

    有两个特殊的伪句柄RTLD_DEFAULTRTLD_NEXT。前者将使用默认库搜索顺序查找所需符号的第一个匹配项。后者将在当前库之后的搜索顺序中查找下一个函数。这使得人们可以在另一个共享库中的函数中提供一个包装。

    dlclose()

    函数dlclose()递减动态库句柄句柄的引用计数。如果引用计数下降到零,并且没有其他加载的库使用它中的符号,则动态库将被卸载。

    函数dlclose()成功时返回0,错误时返回非零值。

    过时的符号_init()和_fini()

    链接器识别特殊符号_init_fini。如果动态库导出名为_init()的例程,那么在dlopen()返回之前,该代码会在加载后执行。如果动态库导出名为_fini()的例程,那么在库被卸载之前调用该例程。如果您需要避免链接到系统启动文件,可以使用gcc(1)-nostartfiles 命令行选项完成此操作。

    不建议使用这些例程或gcc- nostartfiles-nostdlib选项。它们的使用可能会导致不希望的行为,因为构造函数/析构函数将不会执行(除非采取特殊措施)。

    相反,库应该使用__attribute __((构造函数))__attribute __((析构函数))函数属性导出例程。有关这些信息,请参阅gcc信息页面。构造函数例程在dlopen()返回之前执行,而析构函数例程在dlclose()返回之前执行 。

    Glibc扩展名:dladdr()和dlvsym()

    Glibc增加了POSIX未描述的两个功能,其中包含原型

    #define _GNU_SOURCE          / *请参阅feature_test_macros(7)* /
     #include < dlfcn.h >
    
    int dladdr(void * addr ,Dl_info * info );
    
    void * dlvsym(void * handle ,char * symbol ,char * version );
              / *请参阅feature_test_macros(7)* /
     #include < dlfcn.h >
    
    int dladdr(void * addr ,Dl_info * info );
    
    void * dlvsym(void * handle ,char * symbol ,char * version );
    

    函数dladdr()接受函数指针并尝试解析它所在的名称和文件。信息存储在Dl_info 结构中:

    typedef struct {
        const char * dli_fname; / *共享对象的路径名
                                   包含地址* /
        void * dli_fbase; / *共享对象的地址
                                   已加载* /
        const char * dli_sname; / *地址最近的符号的名称
                                   低于地址 * /
        void * dli_saddr; / *指定符号的确切地址
                                   在dli_sname * /
    } Dl_info;
        const char * dli_fname; / *共享对象的路径名
                                   包含地址* /
        void * dli_fbase; / *共享对象的地址
                                   已加载* /
        const char * dli_sname; / *地址最近的符号的名称
                                   低于地址 * /
        void * dli_saddr; / *指定符号的确切地址
                                   在dli_sname * /
    } Dl_info;

    如果找不到符号匹配addr,则将dli_snamedli_saddr设置为NULL。

    dladdr()在错误时返回0,在成功时返回非零值。

    函数dlvsym(),自2.1版以来由glibc提供,与dlsym()相同,但将版本字符串作为附加参数。

    符合

    POSIX.1-2001介绍了dlclose(),dlerror(),dlopen()和dlsym()。

    笔记

    符号RTLD_DEFAULTRTLD_NEXT被定义dlfcn.h中 >仅当_GNU_SOURCE包括之前被定义。

    由于glibc 2.2.3,atexit(3)可用于注册卸载库时自动调用的退出处理函数。

    历史

    dlopen接口标准来自SunOS。该系统也有dladdr(),但不包括dlvsym()。

    错误

    有时候,你传递给dladdr()的函数指针可能会让你感到惊讶。在某些体系结构(特别是i386和x86_64)中,即使用作参数的函数应来自动态链接库,dli_fname和 dli_fbase最终可能会指向您称为dladdr()的对象。

    问题在于函数指针在编译时仍然会被解析,但只是指向原始对象的plt(过程链接表)部分(在请求动态链接器解析该符号后调度该调用)。要解决这个问题,你可以尝试将代码编译为位置无关的:然后,编译器不能在编译时间准备好指针,今天的gcc(1)将生成代码,只是从得到的代码中加载最后的符号地址(全局偏移量表)在传递给dladdr()之前的运行时间。

    加载数学库,并打印2.0的余弦:

    #include < stdio.h >
    #include < stdlib.h >
    #include < dlfcn.h >
    
    INT
    main(int argc,char ** argv)
    {
        void * handle;
        双(*余弦)(双);
        char *错误;
    
       handle = dlopen(“libm.so”,RTLD_LAZY);
        if(!handle){
            fprintf(stderr,“%s \ n”,dlerror());
            出口(EXIT_FAILURE);
        }
    
       dlerror获得(); / *清除任何现有的错误* /
    
       / *写入:cosine =(double(*)(double))dlsym(句柄,“cos”);
           似乎更自然,但C99标准离开了
           从“void *”转换为未定义的函数指针。
           下面使用的任务是POSIX.1-2003(技术文档
           勘误1)解决方法; 请参阅
           POSIX规范的dlsym()。* /
    
       *(void **)(&cosine)= dlsym(句柄,“cos”);
    
       如果((error = dlerror())!= NULL){
            fprintf(stderr,“%s \ n”,错误);
            出口(EXIT_FAILURE);
        }
    
       printf(“%f \ n”,(* cosine)(2.0));
        dlclose(手柄);
        出口(EXIT_SUCCESS);
    }stdio.h >
    #include < stdlib.h >
    #include < dlfcn.h >
    
    INT
    main(int argc,char ** argv)
    {
        void * handle;
        双(*余弦)(双);
        char *错误;
    
       handle = dlopen(“libm.so”,RTLD_LAZY);
        if(!handle){
            fprintf(stderr,“%s \ n”,dlerror());
            出口(EXIT_FAILURE);
        }
    
       dlerror获得(); / *清除任何现有的错误* /
    
       / *写入:cosine =(double(*)(double))dlsym(句柄,“cos”);
           似乎更自然,但C99标准离开了
           从“void *”转换为未定义的函数指针。
           下面使用的任务是POSIX.1-2003(技术文档
           勘误1)解决方法; 请参阅
           POSIX规范的dlsym()。* /
    
       *(void **)(&cosine)= dlsym(句柄,“cos”);
    
       如果((error = dlerror())!= NULL){
            fprintf(stderr,“%s \ n”,错误);
            出口(EXIT_FAILURE);
        }
    
       printf(“%f \ n”,(* cosine)(2.0));
        dlclose(手柄);
        出口(EXIT_SUCCESS);
    }

    如果此程序位于名为“foo.c”的文件中,则可以使用以下命令构建程序:

    gcc -rdynamic -o foo foo.c -ldl

    导出_init()和_fini()的库需要按如下方式编译,使用bar.c作为示例名称:

    gcc -shared -nostartfiles -o bar bar.c

    也可以看看

    ld(1), ldd(1), dl_iterate_phdr(3), rtld-audit(7), ld.so(8), ldconfig(8)

    ld.so信息页面,gcc信息页面,ld信息页面

     

     

     

    以上内容  来自    https://linux.die.net/man/3/dlopen  翻译

    展开全文
  • 1、dlopen 动态库失败原因,我碰到主要是以下几点(碰到新问题之后再完善,先打个点) ①动态库位置没有放对地方,dlopen 时候找不到你想操作的动态库 解决办法:放到指定目录。 ②头文件没有包全,有不能识别的...

    1、dlopen 动态库失败原因,我碰到主要是以下几点(碰到新问题之后再完善,先打个点)
    ①动态库位置没有放对地方,dlopen 时候找不到你想操作的动态库
    解决办法:放到指定目录。
    ②头文件没有包全,有不能识别的函数或者标识符
    解决办法:加一条打印信息,程序运行到这里,会输出不能识别标识符。

    if((handle = dlopen(myso, RTLD_NOW)) == NULL) {  
            printf("dlopen - %sn", dlerror());  
            exit(-1);  
        }  

    或者用ldd(具体看编译交叉链,这里是用 gcc 编写的动态库,其它交叉编译链视具体情况而定)。
    ③makefile 编写问题
    ①没有指定 -fPIC 编译选项 (Position-Independent Code 代码与位置无关);
    ②没有指定 -shared 外部程序可以访问这个动态库。

    展开全文
  • 1 linux提供了加载和处理动态链接库的系统调用       2 主要函数 1) dlopen、  dlopen以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程,打开模式如下: RTLD_LAZY 暂缓决定,等有需要时再解...
  • C++ dlopen mini HOWTO作者:Aaron Isotton <aaron@isotton.com> 2006-03-16译者:Lolita@linuxsir.org 2006-08-05 ------------------------------------------------摘要 如何使用dlopen API动态地加载C++...
  • 动态库(libxxx.so)一种调用方式是在编译的时候的时候指定库名 -lxxx,另一种调用方式是通过dlopen在程序里加载动态库,然后调用相关接口。相关接口比较简单,包括打开动态库,解析库里提供的symbol(函数或者变量)...
  • 1、前言  为了使程序方便扩展,具备通用性,可以采用插件形式...linux提供了加载和处理动态链接库的系统调用,非常方便。本文先从使用上进行总结,涉及到基本的操作方法,关于动态链接库的本质及如何加载进来,需
  • dlopen中几个flag的区别 RTLD LAZY RTLD NOW RTLD GLOBAL
  • 动态库使用实例:dlopen

    2012-12-28 11:37:49
    动态库使用实例:dlopen 1, File main.c  #include #include #define NONE "\033[m" #define RED "\033[0;32;31m" extern int g_count; int main(int argc, char **argv) {
  • 比如说我们在需要做到动态加载库插件时就会用到动态装载库的特性(比如像lighthttpd和nginx的动态mod功能),Linux提供了函数来帮助我们做到这件事,主要的几个函数为:dlopen,dlsym,dlclose栗子假设我们一个项目...
  • dlopen 基本定义  功能:打开一个动态链接库  包含头文件:  #include  函数定义:  void * dlopen( const char * pathname, int mode );  函数描述:  在dlopen的()函数以指定模式打开...
  • 像window调用库文件一样,在linux下,也有相应的API因为加载库文件而存在。它们主要是以下几个函数: 函数名 功能描述 dlopen 打开对象文件,使其可被程序访问 dls
  • https://github.com/gaffe23/linux-inject ...核心原理:1、获取目标程序函数(__libc_dlopen_mode、malloc、free)的地址;2、获取一段可执行的内存地址;3、将汇编注入代码写入这段内存地址;4、通过int3断点来查...
  • main.cpp:(.text+0x19): undefined reference to `dlopen'main.cpp:(.text+0x22): undefined reference to `dlerror'main.cpp:(.text+0x62): undefined reference to `dlsym'需要在编译时加上-ldl。 将原来的编译...
  • linux使用void *dlopen(const char *filename, int flag)调用so动态库时, 其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含义分别为: RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量...
  • dlopen 基本定义 功能:打开一个动态链接库 [喝小酒的网摘]http://blog.const.net.cn/a/17154.htm 包含头文件:  #include 函数定义:  void * dlopen( const char * pathname, int mode );  函数描述...
  • 幸福来得太突然:http://stackoverflow.com/questions/956640/linux-c-error-undefined-reference-to-dlopen  work in Linux with c++ (eclipse) and want to use a library. Eclipse shows me an error: ...
1 2 3 4 5 ... 20
收藏数 9,195
精华内容 3,678
关键字:

dlopen linux