0x04_静态库/动态库制作


静态库

静态库名字以lib开头,以.a结尾。

静态库制作步骤:

  • 写好源代码。

  • 编译源代码生成.o文件。

    gcc -c add.c -o add.o
    gcc -c sub.c -o sub.o
    
  • 制作静态库

    ar rcs libname.a add.o sub.o ...
    

使用静态库:

gcc test.c libname.a -o a.out

静态库使用时,是直接编译到文件里的。

头文件对应

对于未定义未声明的函数,编译器隐式声明返回值为int的形式。如果函数不是返回的int,则隐式声明失效,会报错。

使用头文件的方法加载静态库:

#ifndef _MYMATH_H_
#define _MYMATH_H_

int add(int, int);
int sub(int, int);

#endif

gcc test.c libmymath.a -o test
如果静态库和头文件在其他目录:
gcc test.c ./lib/libmymath.a -o a.out -I ./inc

动态库

写在源代码里面的函数,相对main函数偏移是一定的,链接时,回填main函数地址后,其源代码里的函数也就得到了地址。

动态库里的函数会用一个@plt来标识,当动态库加载到内存时,再用加载进去的地址将@plt替换掉。

动态库制作步骤:

  • 写好源代码。

  • 编译源代码生成.o文件,生成与位置无关的代码。

    gcc -c add.c -o add.o -fPIC
    gcc -c sub.c -o sub.o -fPIC
    
  • 制作动态库。

    gcc -shared -o libname.so add.o sub.o
    

使用动态库:-l指定库名,-L指定库路径,库名要去掉lib和.so

gcc test.c -o a.out -l name -L ./lib -I ./inc

执行a.out出错。

./a.out
./a.out: error while loading shared libraries: libname.so: cannot open shared object file: No such file or directory

错误分析

链接器:工作于链接阶段,工作时需要-l和-L。

动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。

  1. 需要指定动态库路径并使其生效,再执行文件,可通过环境变量指定:

    export LD_LIBRARY_PATH=./lib
    

    但仅在当前终端生效,因为环境变量是进程的概念,关闭终端后再打开,是两个进程,环境变量发生了变化。要想永久生效,需要修改bash的配置文件:vi ~./bashrc,追加export LD_LIBRARY_PATH=./lib(一般写绝对路径)。修改后需要使配置文件立即生效:

    . ~/.bashrc 或
    source .bashrc 或
    重开终端
    
  2. 拷贝自定义动态库到/lib(标准C库所在目录位置)。

  3. 配置文件:

    sudo vi /etc/ld.so.conf
    写入动态库绝对路径,保存
    sudo ldconfig -v
    使得配置文件生效
    

使用ldd a.out查看程序是否动态链接成功。