UNIX 动态库和静态库
2015-11-13 17:38
302 查看
动态库,又叫做共享对象库,以.so结尾。使用动态库时,编译器并不直接在编译的时候将代码嵌入到目标文件中,而是等到运行时调用相应的函数,才加载代码。
静态库,又叫做归档文件,以.a结尾。使用静态库的时候,编译器在编译过程中直接将代码嵌入到目标文件中,所以一旦完成编译,那么静态库可以不需要了。
1、编写静态库以及使用静态库
首先编写hello.h文件。
然后编写hello.c文件。
然后编写main.c。
我们使用gcc -c hello.c得到二进制目标文件hello.o,然后使用ar命令生成静态链接库libhello.a。
ar -cru libhello.a hello.o
指定链接库对main.c进行编译链接生成可执行文件main.out
gcc -o main.out -L. -lhello main.c
执行main.out文件得到结果:
这样就完成从编写静态链接库到使用静态库的全部过程。
2、编写动态库并且使用动态库
现在我们来完成动态链接库的编写。
还是上面的hello.h hello.c main.c文件,我们生成动态链接库libhello.so。
使用命令gcc -c hello.c -fPIC生成hello.o目标文件,使用gcc -shared将hello.o加入到动态库libhello.so中,
gcc -shared hello.o -o libhello.so
编译链接main.c
gcc main.c -o main.out -L. -lhello
配置LD_LIBRARY_PATH的内容包含当前目录:
:.
执行main.out得到下面的运行情况。
三、程序中显式加载动态库
还是按照前面的步骤,生成动态库libhello.so,然后在main.c程序中显式的加载动态库,具体见代码:
使用gcc -ldl main.c -o main.out生成可执行程序。执行main.out的时候也需要寻找动态库的路径中包含当前目录,也就是同样使用export LD_LIBRARY_PATH=.。然后执行可执行程序得到的结果与2中的结果相同。
void *dlopen(const char *filename, int flag);
其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含义分别为:
RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。
RTLD_NOW:与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为:
: undefined symbol: xxxx.......
RTLD_GLOBAL:它的含义是使得库中的解析的定义变量在随后的其它的链接库中变得可以使用。
静态库,又叫做归档文件,以.a结尾。使用静态库的时候,编译器在编译过程中直接将代码嵌入到目标文件中,所以一旦完成编译,那么静态库可以不需要了。
1、编写静态库以及使用静态库
首先编写hello.h文件。
然后编写hello.c文件。
然后编写main.c。
我们使用gcc -c hello.c得到二进制目标文件hello.o,然后使用ar命令生成静态链接库libhello.a。
ar -cru libhello.a hello.o
指定链接库对main.c进行编译链接生成可执行文件main.out
gcc -o main.out -L. -lhello main.c
执行main.out文件得到结果:
这样就完成从编写静态链接库到使用静态库的全部过程。
2、编写动态库并且使用动态库
现在我们来完成动态链接库的编写。
还是上面的hello.h hello.c main.c文件,我们生成动态链接库libhello.so。
使用命令gcc -c hello.c -fPIC生成hello.o目标文件,使用gcc -shared将hello.o加入到动态库libhello.so中,
gcc -shared hello.o -o libhello.so
编译链接main.c
gcc main.c -o main.out -L. -lhello
配置LD_LIBRARY_PATH的内容包含当前目录:
export LD_LIBRARY_PATH=/usr/local/lib
:.
执行main.out得到下面的运行情况。
三、程序中显式加载动态库
还是按照前面的步骤,生成动态库libhello.so,然后在main.c程序中显式的加载动态库,具体见代码:
使用gcc -ldl main.c -o main.out生成可执行程序。执行main.out的时候也需要寻找动态库的路径中包含当前目录,也就是同样使用export LD_LIBRARY_PATH=.。然后执行可执行程序得到的结果与2中的结果相同。
void *dlopen(const char *filename, int flag);
其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含义分别为:
RTLD_LAZY:在dlopen返回前,对于动态库中存在的未定义的变量(如外部变量extern,也可以是函数)不执行解析,就是不解析这个变量的地址。
RTLD_NOW:与上面不同,他需要在dlopen返回前,解析出每个未定义变量的地址,如果解析不出来,在dlopen会返回NULL,错误为:
: undefined symbol: xxxx.......
RTLD_GLOBAL:它的含义是使得库中的解析的定义变量在随后的其它的链接库中变得可以使用。
相关文章推荐
- 下载百度地图瓦片的方法
- gcc 编译动态库和静态库
- tortoise的3D动画
- GridView加载图片混乱
- 浅谈排序
- jquery实践案例--验证手机号码
- C#中Encoding.Unicode与Encoding.UTF8的区别
- web模板引擎--Mustache
- 隐藏.aspx后缀名
- c#访问php 小知识
- C#中Encoding.Unicode与Encoding.UTF8的区别
- Android之zxing二维码生成于识别
- Gson+JsonPath+泛型 java json解析工具类
- cocoaPods的安装和使用教程(附带图)
- mysql中表中字段中值的删除和添加
- jsp+servlet+javabean
- HttpURLConnection-POST-GSON
- kali 国内镜像源,以及PD_tools,Vm_tools的安装
- codeforces 390B Inna, Dima and Song
- 开源ImageFilter库For IOS源码发布