美文网首页
linux共享库

linux共享库

作者: 不懂球的2大业 | 来源:发表于2019-10-25 23:51 被阅读0次

    共享库:

    1.概念

    2.生成一个共享库

    • 代码结构:
      实现一个四则运算的共享库:
    ├── add.cpp
    ├── common.h
    ├── dev.cpp
    ├── main.cpp
    ├── mul.cpp
    └── sub.cpp
    

    common.h文件:

    #ifndef _COMMONH_
    #define _COMMONH_
    
    int add(int a,int b);
    
    int sub(int a,int b);
    
    int mul(int a,int b);
    
    int dev(int a,int b);
    
    #endif
    

    add.cpp文件:

    int add(int a,int b){
        return (a+b);
    }
    

    sub.cpp文件:

    int sub(int a,int b){
        return (a-b);
    }
    

    mul.cpp文件:

    int mul(int a,int b){
        return (a*b);
    }
    

    dev.cpp文件:

    int dev(int a,int b){
        return (a/b);
    }
    

    main.cpp文件:

    #include <iostream>
    #include "common.h"
    
    using namespace std;
    
    int main(){
        cout << "begin():" <<endl;
        cout << "test add:"<<add(4,1)<<endl;
        cout << "test sub:"<<sub(4,1)<<endl;
        cout << "test mul:"<<mul(4,1)<<endl;
        cout << "test dev:"<<dev(4,1)<<endl;
        return 0;
    }
    
    • 步骤:
      第一步:将函数库代码只编译不链接,生成与位置无关的.o文件
    #输入命令:
    g++ -fPIC -c add.cpp sub.cpp mul.cpp dev.cpp
    

    说明:其中,fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
    结果:

    ├── add.cpp
    ├── add.o
    ├── common.h
    ├── dev.cpp
    ├── dev.o
    ├── main.cpp
    ├── mul.cpp
    ├── mul.o
    ├── sub.cpp
    └── sub.o
    

    第二步:生成共享库

    #输入命令:
    g++ -shared -Wl,-soname,libmycal.so.1 add.o sub.o mul.o dev.o -o libmycal.so.1.10 
    

    说明:-shared表示生成共享库;-Wl表示告诉编译器将后面的参数传递给链接器,于Wl来说,它的参数分割是用","。-soname是告诉编译器共享库的soname是libmycal.so.1;生成的目标文件是libmycal.so.1.10,是共享库的realname。这里我们对soname和realname进行说明:realname是动态库文件的真实的名字,记录了共享库的主版本和次版本号,本例中libmycal.so.1.10,主版本号为1,次版本号为10;而soname只记录了共享库的主版本号,本例中的soname为libmycal.so.1,只记录了主版本号1(soname一般是个软链接,指向realname)。
    结果:生成共享库libmycal.so.1.10。

    ├── add.cpp
    ├── add.o
    ├── common.h
    ├── dev.cpp
    ├── dev.o
    ├── libmycal.so.1.10
    ├── main.cpp
    ├── mul.cpp
    ├── mul.o
    ├── sub.cpp
    └── sub.o
    

    若此时利用生成的共享库与自己编写的程序一起编译,则会报错,例如我们main.cpp与共享库一起编译:

    #输入命令:
    g++ main.c libmycal.so.1.10 -o app
    

    结果:生成目标程序app

    ├── add.cpp
    ├── add.o
    ├── app
    ├── common.h
    ├── dev.cpp
    ├── dev.o
    ├── libmycal.so.1.10
    ├── main.cpp
    ├── mul.cpp
    ├── mul.o
    ├── sub.cpp
    └── sub.o
    

    此时执行app,会报错:

    ./app: error while loading shared libraries: libmycal.so.1: cannot open shared object file: No such file or directory
    

    原因:有了共享库,但没有加入系统路径。
    接着我们查看app所依赖的库:

    #输入命令:
    ldd app
    

    结果:

    linux-vdso.so.1 (0x00007fff11b9c000)
    libmycal.so.1 => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0a30697000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a302a6000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0a2ff08000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f0a30c23000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0a2fcf0000)
    

    我们看到libmycal.so.1 => not found,即libmycal.so.1这个库系统没有找到
    第三步:修改系统配置文件,将共享库为系统所共享
    首先修改配置文件,将当前共享库路径加入配置文件

    #输入命令:
    sudo vi /etc/ld.so.conf
    

    说明:ld.so.conf为系统共享库的配置文件,打开后将当前路径加入即可。
    之后更新库:

    #输入命令:
    sudo ldconfig -v
    

    结果:自动生成soname软连接,即下面的libmycal.so.1(指向realname)

    ├── add.cpp
    ├── add.o
    ├── app
    ├── common.h
    ├── dev.cpp
    ├── dev.o
    ├── libmycal.so.1 -> libmycal.so.1.10
    ├── libmycal.so.1.10
    ├── main.cpp
    ├── mul.cpp
    ├── mul.o
    ├── sub.cpp
    └── sub.o
    

    此时再执行app,可以得到结果:

    begin():
    test add:5
    test sub:3
    test mul:4
    test dev:4
    

    第四步:生成linkname

    #输入命令:
    ln -s libmycal.so.1.10 libmycal.so
    

    libmycal.so为linkname,linkname相比soname和realname,没有记录库的版本号,一般用于makefile中,soname只记录主版本号,realname记录主版本和次版本。linkname和soname均指向realname。
    link name(libmycal.so)->real name(libmycal.so.1.10)
    so name(libmycal.so.1)->real name(libmycal.so.1.10)

    相关文章

      网友评论

          本文标题:linux共享库

          本文链接:https://www.haomeiwen.com/subject/cmwlvctx.html