扩展:
- 描述:
a. 动态库也叫共享库
b. 动态库把对一些库函数的链接载入推迟到程序运行的时期(runtime)。
c. 可以实现进程之间的资源共享。
d. 将一些程序升级变得简单。
e. 甚至可以真正做到链接载入完全由程序员在程序代码中控制。
f. 动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”。
g. windows共享库是以 .dll 为后缀的文件。 - 特点:
a. 在程序编译时并不会被链接到目标代码中,而是在程序运行是才被载入,系统会在动态库环境变量所指定的目录下去找对应名字的动态库。
b. 在程序运行时还需要动态库存在,
c. 代码体积较小
d. 不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
- 创建动态库(测试例程在结尾):
a. 将库源文件编译成.o的目标文件–> gcc -c mylib.c -o mylib.o //将.c文件生成.o文件
b. 将.o文件制作成动态库文件 --> gcc [-shared] -fPIC -o libmylib.so mylib.o //这里的-shared是默认的,不写也可以 ;-fPIC 创建与地址无关的编译程序
c. 编译test.c 同时链接制作的动态库 --> gcc -o test test.c -L. -lmylib // -L库的路径 -l库名 - 使用ldd命令查看可执行程序所依赖的动态库:
可以看到libmylib.so动态库没有找到,需要配置该动态库的路径。
- 配置该动态库路径位置路径 :
动态库默认路径为/lib 或者 /usr/lib,有以下方法配置。
a. 方法1:将libmylib.so动态库放到/lib 或者 /usr/lib目录下。
b. 方法2:将动态库所在的路径加入配置文件: /etc/ld.so.conf 的后面,如下:
打开文件: sudo vim /etc/ld.so.conf
使用pwd命令查看当前libmylib.so动态库所在的路径
ld.so.conf文件里添加libmylib.so动态库的路径,如下一行:
/media/sf_VirtualBox_share/库的制作
运行动态链接库管理命令:sudo ldconfig
c. 方法3:将动态库所在的路径临时加入到环境变量中: LD_LIBRARY_PATH
执行下面的命令:
export LD_LIBRARY_PATH=./
./表示将当前路径临时加入到环境变量中,也就是这个路径–>
/media/sf_VirtualBox_share/库的制作
注意: 这个方法只对当前使用的shell终端有效。
- 再次使用ldd命令查看可执行文件所依赖的动态库
可以看到libmylib.so库找到了。
- 注意:
将程序与动态库建立关系时,-L参数用于指定动态库的具体路径。-L.表示所要链接的库在当前目录下。而建立链接后需要把动态库放到指定的位置,这样在可执行程序运行时能正确加载动态库。 - ldconfig命令 :
ldconfig 命令的用途,主要是在默认搜寻目录 (/lib和/usr/lib) 以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库,进而创建出动态装入程序 (ld.so) 所需的连接和缓存文件.缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。 - 动态库与静态库混合连接
如果只使用–shared(默认选项)会造成所有的库都使用动态链接的方式。这时候需要使用 - Wl,option将option作为一个选项传递给链接器,链接器就可以让后面的库进行不同方式的链接。比如 gcc -L. -o test test.c -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic -lmysharelib。这里需要保证动态链接放在后面,以让动态库(如标准库)能在默认的共享库路径去寻找共享库。也可以写成 gcc -L. -o test test.c -Wl,-Bdynamic -lmysharelib -Wl,-Bstatic -lmystaticlib -Wl,-Bdynamic。
- 测试例程:
mylib.c 文件
int myplus(int a,int b);
int mysub(int a,int b);
int myplus(int a,int b)
{
return a + b;
}
int mysub(int a,int b)
{
return a - b;
}
test.c 文件
#include <stdio.h>
int myplus(int a,int b);
extern int mysub(int a,int b);
extern int main(void)
{
int a,b;
printf("请输入a和b:");
scanf("%d%d",&a,&b);
printf("%d + %d = %d\n",a,b,myplus(a,b));
printf("%d - %d = %d\n",a,b,mysub(a,b));
return 0;
}