精华内容
下载资源
问答
  • 大神们,我想查看linux 动态库中方法的详细定义,问有啥方法或工具能否实现?????
  • linux下制作一个动态库

    千次阅读 2017-01-01 20:59:28
    制作一个动态库 我们可以使用gcc工具来制作一个动态库 示例:自己制作一个动态库,库函数的功能是传递一个字符串并输出。 第一步:需要准备3个文件:hello.h、hello.c、test.c。其中hello.h和hello.c用于制作动态...
    制作一个动态库
    我们可以使用gcc工具来制作一个动态库
    示例:自己制作一个动态库,库函数的功能是传递一个字符串并输出。
    第一步:需要准备3个文件:hello.h、hello.c、test.c。其中hello.h和hello.c用于制作动态库,test.c是测试程序主函数

    第二步:使用gcc编译生成动态库
    gcc hello.c -fPIC -c -o hello.o
    gcc hello.o -shared -o libmyhello.so
    (或者直接一步:gcc hello.c -fPIC -shared -o libmyhello.so)
    gcc参数解析:
    ⒈-fPIC(或-fpic):表示编译为位置独立的代码。位置独立的代码即位置无关代码,在可执行程序加载的时候可以存放在内存内的任何位置。若不使用该选项则编译后的代码是位置相关的代码,在可执行程序加载时是通过代码拷贝的方式来满足不同的进程的需要,没有实现真正意义上的位置共享。
    ⒉-shared:指定生成动态链接库

    ldd hello
    linux-gate.so.1 => (0xb77b0000)
    libmyhello.so => not found
    libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75f6000)
    /lib/ld-linux.so.2 (0xb77b1000)
    第三步:定位自己制作的动态库
    为了让系统能成功找到自己制作的动态库,需要定位到该动态库的位置。有三种方式:
    ⑴把自己制作的库拷贝到/usr/lib和/lib下。
    ⑵在LD_LIBRARY_PATH环境变量中添加自己制作的库所在的位置。/
    ⑶添加/etc/ld.so.conf.d/XXX.conf文件(XXX需要自己命名),把库所在的路径添加到文件末尾并执行ldconfig刷新。 //对所用用户有效


    第一种:将库拷贝到/usr/lib和/lib下。
    sudo cp libmyhello.so /usr/lib
    sudo cp libmyhello.so /lib
    此时再执行./hello即可得到正确的显示结果。

    第二种:修改LD_LIBRARY_PATH环境变量:
    sudo vim /etc/bash.bashrc 对所有用户生效 或者修改 ~/.bashrc 这样就只对当前用户生效

    在文件最后,添加:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/linux/file/dongtaiku
    保存退出,重启终端,此时再执行./hello即可得到正确的显示结果。。

    第三种:添加/etc/ld.so.conf.d/XXX.conf文件
    sudo vim /etc/ld.so.conf.d/my.conf
    在文件内添加动态库的目录
    /home/linux/file/dongtaiku
    保存退出,执行ldconfig使设置生效
    sudo ldconfig

    第四步:修改编译时的搜索库路径
    方法一:可以直接在gcc编译时 -L加库路径
    方法二:添加库路径至LIBRARY_PATH环境变量

    第五步:
    创建动态库的同时那以避免我们会使用到头文件
    我们应该修改头文件的路径的环境变量C_LIBRARY_PATH
    展开全文
  • Linux动态库依赖其它动态库的问题

    千次阅读 2019-11-15 11:17:45
    这两天在编写一个插件系统Demo的时候,发现了个很奇怪的问题:插件加载器已经链接了ld,但是应用程序在链接插件加载器的时候,却还需要显式的来链接ld。否则就会报:DSO missing from command line。这个报错...

    1 前言

    这两天在编写一个插件系统Demo的时候,发现了个很奇怪的问题:插件加载器中已经链接了ld库,但是应用程序在链接插件加载器的时候,却还需要显式的来链接ld库。否则就会报:DSO missing from command line。这个报错翻译过来就是没有在命令行中指定该动态库
    这个报错就很搞事了,你说你明明知道需要哪个库,为什么不直接帮我链接呢,非得我显示的在命令行中指定呢?

    2 现象描述

    问题可以简单描述为:当链接可执行文件时,依赖于libA.so,而libA.so又依赖于libB.so,而且可执行文件中还直接调用了libB.so中的函数,那么此时链接就会出现错误。

    2.1 问题发生的前置条件

    • libA.so在编译过程中显式的链接了libB.so
    • 可执行文件中使用了libB.so的函数
    • binuntils版本 ≥ 2.22

    2.2 Talk is cheap. Show me the code

    话不多说,先看看可以复现改问题的代码吧

    libB.so的源码:

    #include <stdio.h>
    
    int funB1(){
    
        printf("in funB1");
    
        return 0;
    }
    
    int funB2(){
    
        printf("in funB2");
    
        return 0;
    }
    
    

    这里面有两个函数:funB1funB2
    其中funB1函数会被libA调用,而funB2会被可执行文件调用。

    编译libB.so:

    $ gcc libB.cpp -fPIC -shared -o libB.so
    

    libA.so的源码:

    #include <stdio.h>
    
    int funB1();
    
    int funA1(){
    
        printf("in funA1 \n");
    
        funB1();
    
        return 0;
    }
    

    该库中只有一个函数funA1,该函数在内部调用了libB中的funB1函数。且该函数会被可执行文件调用。

    编译libA.so:

    $ gcc libA.cpp -fPIC -shared -o libA.so -Wl,-rpath=./ -L./ -lB
    

    main.cpp的源码:

    int funA1();
    int funB2();
    
    int main(){
    
        funA1();
        funB2();
    
        return 0;
    }
    

    编译main.cpp:(复现错误的编译方法)

    gcc main.cpp -L./ -lA
    

    当我们按照上面的指令编译main.cpp的时候,便报错了。

    /usr/bin/ld: /tmp/ccDQXTKy.o: undefined reference to symbol '_Z5funB2v'
    .//libB.so: error adding symbols: DSO missing from command line
    collect2: error: ld returned 1 exit status
    
    

    (问号.jpg)这,这GCC不是搞事吗,你明明知道我需要连接libB.so为啥就不帮我链接上去呢?难道我libA.so没有指明要使用libB.so?我们使用下面的指令来看一下

    $ ldd libA.so
    

    得到如下信息:

    	linux-vdso.so.1 =>  (0x00007ffd09def000)
    	libB.so => ./libB.so (0x00007fc513d7d000)
    	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc5139b3000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007fc514181000)
    
    

    明明libA.so已经显式的指明我要依赖libB.so了,那为啥在编译main.cpp的时候链接了libA.so,GCC却还要我们显式的链接libB.so呢?

    3 答案

    答案很简单,那就是GCC就是想要你显式链接呗。(你是编译器,你牛好吧。)那这是为啥呢?
    官方一点的答案就是,自从binutils 2.22版本以后,如果你在程序中使用了你依赖的动态库所依赖的动态库中的函数时,你就必须显式的指定你依赖的动态库所依赖的动态库。

    说那么多,我们更想知道的是,通过修改什么参数可以解决这个问题呢?因为你可能不想在编译程序的时候要把动态库所依赖的所有动态库都显示链接一遍。

    4 究极答案

    实际上,这是binutils在2.22版本以后,默认把--no-copy-dt-needed-entries这个选项打开了。当打开了这个选项的时候,编译器在链接的时候是不会递归的去获取依赖动态库的依赖项的,于是就会出现上述的问题。关于该配置项的详细说明如下:

       --copy-dt-needed-entries
       --no-copy-dt-needed-entries
           This option affects the treatment of dynamic libraries referred to by DT_NEEDED tags inside ELF dynamic libraries mentioned on the command line.  Normally the linker won't add a DT_NEEDED
           tag to the output binary for each library mentioned in a DT_NEEDED tag in an input dynamic library.  With --copy-dt-needed-entries specified on the command line however any dynamic
           libraries that follow it will have their DT_NEEDED entries added.  The default behaviour can be restored with --no-copy-dt-needed-entries.
    
           This option also has an effect on the resolution of symbols in dynamic libraries.  With --copy-dt-needed-entries dynamic libraries mentioned on the command line will be recursively
           searched, following their DT_NEEDED tags to other libraries, in order to resolve symbols required by the output binary.  With the default setting however the searching of dynamic
           libraries that follow it will stop with the dynamic library itself.  No DT_NEEDED links will be traversed to resolve symbols.
    

    大概意思就是,跟在--no-copy-dt-needed-entries它后面的库都不会遍历其依赖项,使用--copy-dt-needed-entries则相反。也就是使用下面的指令来编译mian.cpp就可以避免该问题了。

    $ gcc main.cpp -L./ -Wl,--copy-dt-needed-entries -lA
    

    题外话

    在Linux的ELF文件中,如果依赖于其他的动态库,那么改ELF文件会存在一个.dynamic的段,这个段里面会记录其依赖的动态库信息,其标志位为DT_NEEDED。

    最近为公司开发的开源超级轻量级插件系统(https://github.com/HSRobot/HPlugin),欢迎大家交流讨论。

    5 参考文档

    1,DSO missing from command line原因及解决办法:https://segmentfault.com/a/1190000002462705
    2,折腾gcc/g++链接时.o文件及库的顺序问题: https://www.cnblogs.com/OCaml/archive/2012/06/18/2554086.html#sec-1-4-1

    展开全文
  • linux系统下,当系统存在多相同命名的动态库(.so)时,ldconfig只为执行程序链接最后找到的库,而之后找到的库虽然通过“ifconfig -p”可以看到库路径信息,但不会被链接到执行程序。   在实际编程,...

      在linux系统下,当系统中存在多个相同命名的动态库(.so)时,ldconfig只为执行程序链接最后找到的库,而之后找到的库虽然通过“ifconfig -p”可以看到库路径信息,但不会被链接到执行程序。

      在实际编程中,如果多个项目都用到某个动态库(比如libteaa.so,存在有多个并且在不同路径下),而且libteaa.so内的某个函数实现不同,部分程序编译或执行时将会出现异常情况。

    举两个简单例子:

    1. a程序需要调用libteaa.so内的add函数为int add(int a, int b),而b程序需要调用libteaa.so内的函数为int add(int a)。
    2. a程序需要调用libteaa.so内的add函数内部为return a + b,而b程序需要调用libteaa.so内add函数内部为return a + a + b。

      上述示例执行ldconfig后,如果链接的是a程序的libteaa.so库,那么b程序将会出错。针对这种情况,我们可以通过修改动态库名称来达到同时链接多个库,比如b程序的libteaa.so改为libtebb.so。

    接下来,我们通过以下内容了解如何修改动态库名称


    1. 查看系统中相同命名的动态库

    在这里插入图片描述

    图1 ldconfig -p查看同名称库路径

    参考图1, 执行ldconfig -p | grep libteaa,可以看到两个libteaa.so,但只有下面这个会被链接到执行程序(图2)。

    在这里插入图片描述

    图2 ldd 程序名查看链接库路径

    2. 查看库文件中是否包含库名称

    在这里插入图片描述

    图3 查看库文件内容

      首先执行hexdump -C libteaa.so > tmp,把文件内容保存入tmp文件中,然后vim打开文件可以看到文件偏移量、字节的十六进制、ASCII字符内容,参考图3。

      在文件中,搜索libteaa,在ASCll字符信息中如果有libteaa.so(库名称),表示动态库可以通过修改名称成为另一个动态库(解决同名问题)。


    3. 修改库文件名称

      修改库文件中的名称需要考虑对齐的情况,比如libteaa可以修改teaa内容,也就是四个字节,比如改为libtebb或libaabb。如果修改后的名称少于或超出原名称长度将会损坏名称之后的内容,造成库执行失败的情况。

      库名称修改方式为: sed -i “s/libteaa/libtebb/” libteaa.so,表示把libteaa.so中的libteaa替换为libtebb。这种情况只能在hexdump -C可以查到库名称的情况下完成修改,否则无效(未替换)。

    在这里插入图片描述

    图4 再次通过 ldconfig -p查看库路径

      库名称修改完成后,执行sudo ldconfig,可以看到libtebb.so库和库路径,但还没结束。现在的libtebb.so属于软连接文件,它链接的还是原来的libteaa.so。
      接下来执行 mv libteaa.so libtebb.so,把库名称与库文件内的名称同步,然后可以通过 -ltebb加载这个libtebb.so库了。

    4. 遇到的问题

      测试过程中,遇到部分库文件内未找到库名称的情况,一般发生在直接用gcc编译动态库。针对这个问题,可以通过Cmake脚本编译动态库。

    在这里插入图片描述

    图5 使用新库执行程序

      经过后续的测试,改名后的库与原来的库不冲突,算是解决同名库的一种方式吧!

    展开全文
  • linux动态库.so文件和.a文件是否是独立可用的? 比如我有dynamic.so和static.o文件,这两文件是否可能依赖于别的so和a文件,甚至有没有可能依赖于.cpp/.c文件,或者只可能依赖其中的种?即so和a文件是否一定...
  • linux中加载动态库

    千次阅读 2013-11-02 13:12:07
    Linux中可以动态加载库...1. 先生成一个动态库libtest.so /* test.c */ #include #include void test1(int no) {  printf("*****************************************\n");  printf("This is test1, the
    在Linux中可以动态加载库,其使用方法如下:
    1. 先生成一个动态库libtest.so
    /* test.c */
    #include <stdio.h>
    #include <stdio.h>
    void test1(int no)
    {
         printf("*****************************************\n");
         printf("This is test1, the number is %d.\n", no);
         printf("*****************************************\n");
    }
    void test2(char *str)
    {
         printf("=========================================\n");
         printf("This is test2, the string is %s.\n", str);
         printf("=========================================\n");
    }

    编译库:
    gcc -fPIC -shared -o libtest.so test.c
    这样就可以生成libtest.so动态库。
    在这个库里,定义个两个函数test1,test2,下面将在程序中加载libtest.so,然后调用test1,test2。

    2. 动态加载libtest.so
    /* main.c */
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <dlfcn.h> /* 必须加这个头文件 */
    #include <assert.h>

    int main()
    {
         void *handler = dlopen("./libtest.so", RTLD_NOW);
         assert(handler != NULL);
         void (*test1)(int) = dlsym(handler, "test1");
         assert(test1 != NULL);
         void (*test2)(char *) = dlsym(handler, "test2");
         assert(test2 != NULL);
         (*test1)(10);
         (*test2)("hello");
         dlclose(handler);
         return 0;
    }
    /* end */
    在这个程序中,dlopen函数用来打开一个动态库,其返回一个void *的指针,如果失败,返回NULL。
    dlsym返回一个动态库中的一个函数指针,如果失败,返回NULL。
    dlclose关闭指向动态库的指针。
    编译的时候需要加上 -ldl
    gcc -o main main.c -ldl(编译时要使用共享库dl 其中有dlopen dlsynm dlerror dlclose 函数)
    运行main,将会看到调用test1,和test2的结果
    展开全文
  • linux加载动态库问题

    千次阅读 2018-09-10 16:12:03
    当我们在linux系统引用动态库时,经常会遇到一个问题,加入我们需要的动态库没有在系统的默认目录下,我们编译时使用-L指定了动态库的路径,编译时没有问题,但是执行调用该动态库的可执行文件时,却提示找不到动态...
  • Linux 动态库的编译和使用

    千次阅读 2019-09-28 21:07:03
    动态库是目标文件的集合,目标文件在动态库中的组织方式是按特殊的方式组织形成的。在动态库中函数和变量的地址是相对地址而不是绝对地址,其真实地址在调用动态库的程序加载时形成的。 动态库的名字有别名...
  • Linux Makefile 静态库动态库应用实例

    千次阅读 2018-04-24 11:10:46
    Linux系统: 静态的创建 gcc -c filen.c ar -cr libname.a file1.o file2.o ... ...如果若干模块一个模块在库中不存在,ar显示一个错误信息,并不替换其他同名的模块。默认的情况下,新的成员增加在库德...
  • Linux使用静态库和动态库

    千次阅读 2016-05-08 16:28:07
    Linux使用静态库和动态库
  • linux动态库soname简介

    千次阅读 2019-06-30 12:17:26
    linux动态库 Linux 支持两种类型的库,每一种库都有各自的优缺点。 静态库包含在编译时静态绑定到一个程序的函数。动态库则不同,它是在加载应用程序时被加载的,而且它与应用程序是在运行时绑定的。 静态库较适宜...
  • linux动态库培析

    千次阅读 2013-05-11 12:57:22
    可以结合动态库来实现c++的反射机制,这样显得多高级,是吧?很好的文章,所以分享一下,单从下面的文章可能很难看到它和c++的反射机制有什么关系,之后如果有时间我会再写篇我自己理解 的c++反射机制的实现。
  • 有时需要分析某个动态库有哪些依赖库,以此来分析可移植性 使用readelf -d命令 测试程序 hello.c #include <stdio.h> extern void test(void); void hello(void) { printf("123123131233\n"); test(); } ...
  • 、基本概念1.1什么是库在windows平台和linux平台下都大量存在着库。本质上来说库是种可执行代码的二进制... 1.2库的种类linux下的库有两种:静态库和共享库(动态库)。二者的不同点在于代码被载入的时刻不同。静
  • Linux系统中动态库的链接和链接选项

    千次阅读 2016-06-28 19:48:09
    动态库的链接和链接选项-L,-rpath-link,-rpath   链接动态库 如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两目录,...
  • 深入剖析Linux动态库在内存的装载

    千次阅读 2018-12-19 10:55:01
    这是之前写的一个总结,现在回过头来看还是有一些收获,可以自己写一个动态库来进行测试,本文是以我自己写的动态库来进行测试的,使用工具readelf。   .so文件是elf格式文件的一种,它遵循elf格式的相关规则,...
  • Linux 动态库剖析

    千次阅读 2011-11-28 20:09:00
    Linux 动态库剖析 进程与 API M. Tim Jones, 顾问工程师, Emulex Corp. M. Tim Jones 是名嵌入式固件架构师,同时也是 Artificial Intelligence: A Systems Approach, GNU/Linux Application Progr
  • Linux动态库原理(二)重定位

    千次阅读 2016-08-12 14:21:14
    前面章《Linux动态库工作原理详解》比较简单浅显的对 Linux 的工作原理进行了阐述,今天打算从 Linux 动态库在加载过程符号的重定位(Relocation)的角度,更加深入的讲解 Linux 动态库的工作原理。 在1980s ...
  • linux动态库so更新

    千次阅读 2019-01-10 16:41:47
    linux更新so库: 不能直接使用cp进行覆盖,源程序直接段错误。 进入/lib文件夹,先删除原来库文件,再放进去新库文件。...动态库生成见之前博客https://blog.csdn.net/hutiewei2008/article/details/84650997 ...
  • 现象:在生成某个动态库比如SDS_Utility.so的时候,需要静态链接某些库,如libboost_log.a, 报上述错误。原因:静态库想链接进动态库,必须满足一定的条件,静态库需要加-fPIC选项编译,编译成Position Independent ...
  • Linux动态库和windows动态库的目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同。但是尽管有差异Linux动态库的windows动态库还是可以移植的,有一些规则以及经验是必须的知道的。  两种系统...
  • 动态库的静态加载  math.c #include&lt;stdio.h&gt; int add(int a,int b) { return a+b; } show.c   #include&lt;stdio.h&gt; int show(int a) { printf("两数之和...
  • linux动态库so调用外部so,运行时出现undefined symbol
  • .库 什么是库,简单的可以说是可执行代码的二进制...linux下静态库(.a)文件,动态库(.so)文件。主要存放函数库的路径有:/lib , /usr/lib. 二.静态库与动态库 1.静态库 这类库的名字一般是libname.a.利用静态库
  • linux动态库的初始化和清理

    千次阅读 2015-03-16 09:26:17
    a. Windows 有 DllMain 入口函数, 而 Linux 则没有。  b. Linux 有特殊函数 _init 和 _fini, 主要是分别用来初始化动态库和关闭的时候 ...具体说, 如果一个动态库里面有一个名字为  "_i
  • linux编译zlib库的动态库so

    千次阅读 2014-12-23 12:12:28
    转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)  zlib一个强大的通用的开源压缩,用途比较广,在windows下能够很容易的编译或者拿到编译成功的二进制文件。但是linux下的比较少,本文记录...
  • Linux链接动态库的方式

    千次阅读 2018-04-21 17:09:41
    Linux下应用程序链接动态库有以下三种方式:改变LD_LIBRARY_PATHexport LD_LIBRARY_PATH=/home/bow/all/program/test/lib_version_test:$LD_LIBRARY_PATH这里/home/bow/all/program/test/lib_version_test是共享库的...
  • linux动态库的使用

    千次阅读 2015-11-06 13:47:41
    编译时与运行时库的路径运行时动态库的路径搜索顺序 编译目标代码时指定的动态库搜索路径(指的是用-wl,rpath或-R选项而不是-L);gcc -Wl,-rpath,/home/arc/test,-rpath,/usr/local/lib test.c 环境变量LD_LIBRARY_...
  • linux动态库加载的秘密

    千次阅读 2018-01-07 13:40:21
    linux 下有动态库和静态... 基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看  # ldd /bin/ls linux-vdso.so.1 => (0x00007fff597ff000) libselinux.so.1 => /lib64/l
  • Linux cJSON库的使用、编译为cJSON动态库 、简述  记--再linux平台下编译cJSON并简单的使用。  cJSONFiles.zip:链接: https://pan.baidu.com/s/16JkSONzRy2ZzAvjUXcoD5Q 提取码: 2cvh  cJSON-master.zip:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 251,582
精华内容 100,632
关键字:

linux动态库中调另外一个动态库

linux 订阅