动态库调用的那些事
调用动态库的两种方式
1. 类似静态库—-头文件
这种方式生成的程序会在启动时候就加载so动态库。
1 | //add.h |
1 | //add.c |
1 | //main.c |
编译生成libadd.so
1 | gcc -shared -fPIC -o libadd.so add.c |
-shared
表明生成共享库如果不加
-fPIC
,则加载.so
文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容, 这就造成每个使用这个.so
文件代码段的进程在内核里都会生成这个.so
文件代码段的copy.每个copy都不一样, 取决于
这个.so
文件代码段和数据段内存映射的位置.另外比较重要的第一点是最好显式添加
-fPIC
表明使用地址无关代码 PIC:Position Independent Code-shared
Produce a shared object which can then be linked with other objects to form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option.[1]
编译main,使用-L./
指定add库在当前目录。
1 | gcc -o main main.c -L./ -ladd |
此时如果不使用-L
来指定动态库路径的话, 可以使用LIBRARY_PATH
1 | export LIBRARY_PATH=LIBDIR1:LIBDIR2:$LIBRARY_PATH |
LIBRARY_PATH
为程序编译期间查找共享库的路径. 开发时,设置LIBRARY_PATH
,以便gcc能够找到编译时需要的动态链接库
2. 使用dlopen/dlsum动态加载动态库—-不使用头文件
这种方式生成的程序会在代码执行到指定行位置加载so动态库。
1 | //add.c |
1 | //main.c |
编译so
,生成libadd.so
1 | gcc -shared -fPIC -o libadd.so add.c |
编译main,不需要指定libadd.so
相关信息进行编译,执行时候会在指定目录加载
1 | gcc -o main main.c -ldl |
一般需要添加LD_LIBRARY_PATH
LD_LIBRARY_PATH
环境变量用于在程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径
1 | export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH |
- 发布和使用时,设置
LD_LIBRARY_PATH
,以便程序加载运行时能够自动找到需要的动态链接库。