Linux静态库和共享库

来源:互联网 发布:淘宝童装店招素材 编辑:程序博客网 时间:2024/06/03 09:25

Linux静态库和共享库


linux库学习笔记

一、什么是库

本质上来说库是一种可执行的二进制形式代码,可以被操作系统载入内存执行。由于windows和linux的本质不同,因此二者库的二进制是不兼容的,本文主要是针对linux系统下的库进行说明的。

二、库的种类

linux下的库有两种:静态库和共享库(动态库)。二者的不同点在于代码被载入的时刻不同。

•      静态库:在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库,因此体积较大。

•      共享库:在程序编译时并不会被连接到目标代码中,只是在生成的可执行程序中简单指定需要使用的库函数信息,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在,因此代码体积较小。

三、库文件的命名规则

•      静态库: libxxxx.a,其中xxxx是该lib的名称

•      共享库: libxxxx.so.major.minor,xxxx是该lib的名称,major是主版本号,minor是副版本号

四、库存在的意义

库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。

现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。

封装

版本管理

共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

五、库的创建与使用

    静态库的创建

Step1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

Step2.ar命令将很多.o转换成静态库,如

#ar crs libhello.a hello.o

    共享库的创建

Step1.由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表

Step2. 由编译器加特定参数编译生成共享库,如

# gcc-shared -fPCI -o libhello.so hello.o

       库的使用

#gcc-o hello main.c -L. –lhello

五、动态库加载的问题

1.    拷贝动态库文件到/lib或/usr/lib去

2.    改变环境变量LD_LIBRARY_PATH

命令:#export LD_LIBRARY_PATH=/home/xxx/lib/

3.    在/etc/ld.so.conf添加库的路径,然后执行ldconfig命令生效

4.    在编译时指定库的搜索路径,-Wl,-rpath=/home/xxx/lib(应该是库在系统中的绝对路径)

5.    动态加载库

六、动态加载库接口

1.    dlopen

函数原型:void*dlopen(constchar *libname,int flag);

功能描述:dlopen必须在dlerror,dlsym和dlclose之前调用,表示要将库装载到内存,准备使用。

如果要装载的库依赖于其它库,必须首先装载依赖库。如果dlopen操作失败,返回NULL值;如果库已经被装载过,则dlopen会返回同样的句柄。

Libname:一般是库的全路径,这样dlopen会直接装载该文件;如果只是指定了库名称,在dlopen会按照下面的机制去搜寻:

a.    根据环境变量LD_LIBRARY_PATH查找

b.    根据/etc/ld.so.cache查找

c.    查找依次在/lib和/usr/lib目录查找。

Flag:表示处理未定义函数的方式,可以使用RTLD_LAZY或RTLD_NOW。

RTLD_LAZY:表示暂时不去处理未定义函数,先把库装载到内存,等用到没定义的函数再说;

RTLD_NOW:表示马上检查是否存在未定义的函数,若存在,则dlopen以失败告终。

2.    dlerror

函数原型:char*dlerror(void);

功能描述:dlerror可以获得最近一次dlopen,dlsym或dlclose操作的错误信息,返回NULL表示无错误。dlerror在返回错误信息的同时,也会清除错误信息。

3.    dlsym

函数原型:void*dlsym(void*handle,const char *symbol);

功能描述:在dlopen之后,库被装载到内存。dlsym可以获得指定函数(symbol)在内存中的位置(指针)。如果找不到指定函数,则dlsym会返回NULL值。但判断函数是否存在最好的方法是使用dlerror函数,

4.    dlclose

函数原型:int dlclose(void*);

功能描述:将已经装载的库句柄减一,如果句柄减至零,则该库会被卸载。如果存在析构函数,则在dlclose之后,析构函数会被调用。

七、与库相关的常用命令

1.    nm:用来列出目标文件的符号清单。

2.    ldd:显示可执行模块的dependency。

八、实例测试

①    编写源文件

hello.c

#include<stdio.h>

void sayhello() 

{

    printf("hello world \n");                                                                                                  

}

libtest.c

#include<stdio.h>                                                                                                            

int main(){

    sayhello();

    return 0;

}

②    编译生成目标文件(.o)

使用命令:$gcc –c -fPIC hello.c

$gcc –c -fPIC libtest.c

③    库文件生成与使用

1.    静态库

使用命令:$ar –crs libhelloa.a hello.o

2.    共享库

使用命令:$gcc -fPIC -shared -o libhellos.so hello.o

3.    编译目标文件

使用命令(使用静态库):$ gcc -o libtesta libtest.o -L. –lhelloa

使用命令(使用共享库):$ gcc -L. -lhello -Wl,-rpath=./ -o libtestslibtest.o

④    結果

$./libtesta

$ helloworld

$./libtests

$ helloworld

使用命令ldd查看依赖,结果如下:


动态加载库实例

①    编写源文件

dlibtest.c

#include<stdio.h>

#include<dlfcn.h>

int main(int argc,char **argv){                                                                                                 

       void *handle;

       int (*func)(void);

       handle=dlopen("./libhellos.so",RTLD_LAZY);

       if(!handle){

              printf("load lib error\n");

              return 1;

       }

       func = (int (*)(void))dlsym(handle, "sayhello");

       if (func == NULL)

       {

              printf("Load symbol myfunction fail, %s\n", dlerror());

              return 2;

       }

       func();

       dlfclose(handle);

       return 0;

}

②    编译

使用命令:$ gcc-o dlibtest dlibtest.c -ldl

③    結果

$./dlibtest

$ helloworld


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 轩辕传奇手游灵宠融合错了怎么办 各尧学生不能用怎么办? 山东一卡通商务卡丢了怎么办 和信通过期了怎么办 和信通过期怎么办延期 和信通过期余额怎么办 超市储蓄卡丢了怎么办 提现提到注销卡怎么办 美通卡过期2年了怎么办 物美美通卡丢失怎么办 网上购物电话留错了怎么办 微信斗牛一直输怎么办 微信斗牛输了钱怎么办 微信举报诈骗不成功该怎么办 沙河拿服装太贵怎么办 包上的暗扣掉了怎么办 银手镯暗扣松老是掉怎么办 包包纽扣锁坏了怎么办 包的纽扣坏了怎么办 包上的纽扣坏了怎么办 洗衣服不小心用了色渍净怎么办 洗衣服不小心沾了卫生纸怎么办 麻料裤子扎皮肤怎么办 衣服没洗干净有点发光怎么办 桑蚕丝衣服脏了发光洗不掉怎么办 厨师衣服的油味怎么办 看上夜场的小姐了怎么办 楼卖完了水吧员怎么办 窗帘短了20公分怎么办 白色鞋子沾油了怎么办 面试时没有正装怎么办 宝宝喝了沐浴露怎么办 开实体童装店没人买怎么办 宝宝一岁半了还不会说话怎么办 十个月宝宝不吃辅食怎么办 八个月宝宝不吃米糊怎么办 八个月宝宝不吃辅食怎么办 六个月宝宝不吃米粉怎么办 4个月婴儿积食怎么办 黑色的衣服泛红怎么办 不听劝的人该怎么办