一、动态库的编译
1. 什么是动态库(共享库)
动态库是可以执行的,静态库不能执行
但动态库没有main,不能独立执行
动态库不会连接成程序的一部分
程序执行时,必须需要动态库文件
2. 工具
ldd 查看程序需要调用的动态库
ldd 只能查看可执行文件(共享库文件或elf文件)
readelf -h (-h表示查看执行文件头)
nm (查看库中的函数符号)
3. 动态库的编译
3.1编译
-c -f pic(可选) (-f 指定文件格式pic 位置无关代码)
3.2 连接
-shared
编译:gcc -c -fpic iotool.c
gcc -c -fpic graphic.c
(非标准)gcc -shared -odemo3.so iotool.o graphic.o
(标准)gcc -shared -olibdemo4.so iotool.o graphic.o
4. 使用动态库
gcc 代码文件名 动态库文件名
gcc 代码文件名 -l库名 -L动态库所在的路径
gcc main.c -ldemo4 -L. -o main
标准命名规则:
lib库名.so
lib库名.a
问题:
4.1 执行程序怎么加载动态库?
4.2 动态库没有作为执行程序的一部分,为什么连接需要制定动态库及目录?
因为连接器需要确认函数在动态库中的位置
动态库的加载:
1. 找到动态库
2. 加载动态库到内存(系统实现)
3. 映射到用户的内存空间(系统实现)
动态库查找规则:
/lib
/user/lib
LD_LIBRARY_PATH环境变量指定的路径中找
设置当前路径为环境变量:
export LD_LIBRARY_PATH=.:~:..:~Walle
缓冲机制:
系统把lib:/user/lib:LD_LIBRARY_PATH里的文件加载到缓冲
/sbin/ldconfig -v 刷新缓冲so中的搜索库的路径
小练习:
输入两个数,计算两个数的和。
要求:输入与计算两个数的和封装成动态库调用
1)inputInt.c
#include <stdio.h> int inputInt(const char* info){ printf("%s\n",info); int r; scanf("%d",&r); return r; }
2)add.c
int add(int a, int b){ return a+b; }
3)main.c
#include <stdio.h> int main(){ int a = inputInt("please input the first number"); int b = inputInt("please input the second number"); int result = add(a,b); printf("the sum of two number is %d\n",result); return 0; }
编译:
[fedora@localhost day02_r3]$ gcc -fpic -c inputInt.c
[fedora@localhost day02_r3]$ gcc -fpic -c add.c
[fedora@localhost day02_r3]$ gcc -fpic -c add.c
连接:
[fedora@localhost day02_r3]$ gcc -shared -o libdemo1.so inputInt.o add.o
使用:
[fedora@localhost day02_r3]$ gcc main.c -omain -ldemo1 -L.
这时候,系统有可能还无法找到动态库的位置。。。
在命令行中输入ldd main,这时候你可能看到以下信息:
[fedora@localhost day02_r3]$ ldd main
linux-gate.so.1 => (0xb77a2000)
libdemo1.so => not found //这一样信息表示系统无法找到你的动态库
libc.so.6 => /lib/libc.so.6 (0x4e092000)
/lib/ld-linux.so.2 (0x4e070000)
linux-gate.so.1 => (0xb77a2000)
libdemo1.so => not found //这一样信息表示系统无法找到你的动态库
libc.so.6 => /lib/libc.so.6 (0x4e092000)
/lib/ld-linux.so.2 (0x4e070000)
这时候需要进行以下操作,告诉系统应该去那里寻找动态库
[fedora@localhost day02_r3]$ export LD_LIBRARY_PATH=.:..:~:~fedora
这时候,再输入ldd main 查看用户执行程序main需要哪些动态库时,我们可以看到以下信息:
[fedora@localhost day02_r3]$ ldd main
linux-gate.so.1 => (0xb779e000)
libdemo1.so => ./libdemo1.so (0xb779b000) //这时就可以找到动态库了,这里找的是当前目录下libdemo1.so
libc.so.6 => /lib/libc.so.6 (0x4e092000)
/lib/ld-linux.so.2 (0x4e070000)
[fedora@localhost day02_r3]$ ldd main
linux-gate.so.1 => (0xb779e000)
libdemo1.so => ./libdemo1.so (0xb779b000) //这时就可以找到动态库了,这里找的是当前目录下libdemo1.so
libc.so.6 => /lib/libc.so.6 (0x4e092000)
/lib/ld-linux.so.2 (0x4e070000)
-----------------------------------动态库的基本使用------------------------------------------------------------
1、编译
gcc -fpic -c inputInt.c
2、连接
gcc -shared -o libdemo1.so inputInt.o add.o
3、使用
gcc main.c -omain -ldemo1 -L.
4、告诉系统去哪里找动态库
export LD_LIBRARY_PATH=.:..:~:~fedora