前言
上一章写了linux下静态链接库的制作使用,现在就讨论一下动态库的制作与使用。
在Windows上动态库是.dll,Linux上是.so
静态链接是在编译时完成的,因此可执行文件中以及包含有所需的静态库,可执行文件可以单独运行;由于动态链接是在程序运行时完成的,可执行文件在加载入内存运行时才会链接共享库,因此可执行文件必需共享库的支持,不能单独运行;
动态库编写
image.png
//add.c
/*************************************************************************
> File Name: add.c
> Author: fujie
> Mail: 1243596620@qq.com
> Created Time: 2020年09月01日 星期二 10时38分21秒
************************************************************************/
int add(int a,int b){
return a+b;
}
//sub.c
/*************************************************************************
> File Name: sub.c
> Author: fujie
> Mail: 1243596620@qq.com
> Created Time: 2020年09月01日 星期二 17时10分14秒
************************************************************************/
int sub(int a,int b){
return a-b;
}
比上一章多了一个sub.c
创建共享库的输入文件可为.c/.cpp文件,用命令参数-shared表示创建共享库,-fpic参数也是必要的,指示编译器生成与位置无关的代码,这样才能实现应用程序之间的资源共享。
这里位置无关代码我在以前的文章中详细讨论过,感兴趣的可以去看看
gcc -shared -fpic -o libtest.so add.c sub.c
这样就在当前目录下生成了 libtest.so文件
动态库使用
//main.c
/*************************************************************************
> File Name: main.c
> Author: fujie
> Mail: 1243596620@qq.com
> Created Time: 2020年09月01日 星期二 16时16分29秒
************************************************************************/
#include
int add(int a,int b);
int sub(int a,int b);
int main(){
printf("sub=%d\n",sub(5,3));
printf("add=%d\n",add(3,3));
}
使用gcc编译
gcc -o main main.c ../lib/libtest.so
运行如下
image.png
共享库搜索路径
1.先找编译目标代码时指定的动态库搜索路径。这里所指的编译时实际就是指的在最后用共享库和main.cpp文件生成可执行文件时直接指定共享库的搜索路径,需要注意的是,这里指定共享库的搜索路径必须同时指出链接时路径和运行时路径,链接器根据给出的链接时路径找到共享库这样才能生成可执行文件,程序运行时需根据运行时路径找到共享库才能运行可执行文件。有两种方法,一种是如上所述直接给出共享库的路径,这里就相当于路径既代表了链接时路径也代表了运行时路径;另一种方法是使用命令参数-L来指定链接时路径,这点和静态库类似就不多说了,然后使用命令参数-Wl(小写L),-rpath=xxxx来指定运行时路径,比如说这里的libcalcusr.so在lib文件夹下,main.cpp在src文件夹下,我要将可执行文件最终输出在bin文件夹下,当前目录为src,就使用以下命令即可:g++ -o ../bin/output_s main.cpp -L../lib -lcalcusr -Wl,-rpath=../lib,其中的-lcalcusr也是在-l参数下的库名简写。
2.再找环境变量LD_LIBRARY_PATH指定的动态库搜索路径。如果此时已经生成了可执行文件,但是可执行文件找不到共享库从而无法运行,那么就可以设置环境变量LD_LIBRARY_PATH来指出共享库的搜索路径。举个例子,生成的可执行文件在bin文件夹下,不管之前链接时是如何指定搜索路径的,总之现在无法找到共享库,而此时共享库位于bin文件夹下,那么就可以使用指令export LD_LIBRARY_PATH=../bin ,这里的右侧路径是相对于当前路径而言的。不过这种方式是治标不治本的, 只是当前链接可行,后面就不行了。
3.再找配置文件/etc/ld.so.conf中指定的动态库搜索路径。打开/etc/ld.so.conf,在文件末尾处加上共享库路径,保存后再在命令行中输入ldconfig命令执行即可。