静态库和动态库的区别

静态库和动态库的区别

什么是库

库:也叫做代码库,把一个或一些目标文件合并在一起方便使用,有静态库和共享库两种。
静态库:在链接时把库的二进制指令赋值到调用模块中。
动态库:也叫作共享库,会和调用者一起加载到内存,到执行调用语句时会从程序的调用位置跳转到共享库中运行。
优缺点:

静态库的优点是运行速度快,但维护麻烦,当静态库中的内容更新后需要重新编译程序,使用静态编译出的可执行文件会比共享库大。
共享库的优点是使用方便,共享库如果发生变化不需要重新编译程序,使用它编译出的可执行文件比使用静态库要小,但运行速度要比静态库慢。
注意:静态库的扩展名是.a,共享库的扩展名是.so,共享库要有执行权限

静态库的创建与使用

1.创建静态库

编辑静态库源码
编译出目标文件:gcc xxx.c - c
把目标文件打包成静态库文件: ar -r libxxx.a x1.o x2.o …
ar 是一个专门控制静态库的命令
-r 把目录文件合并成一个静态库,如果静态库文件已经存在则更新。
-q 向静态库中添加目录文件
-t 查看静态库中有哪些目标文件
-d 从静态库中删除目标文件
-x 把静态库展开为目标文件

2.使用静态库

  1. 直接调用
    把静态库当作目标文件一样,与调用者的目标文件一起合并出可执行文件。
    gcc main.c libcalc.a
    2.通过设置LIBRARY_PATH环境变量来指定库的路径
    gcc main.c -lcalc 需要通过-l来指定库名
    3.通过gcc -L参数来指导库的路径
    gcc main.c _L ./calc/ -lclac

共享库的创建与使用

创建共享库

编辑静态库原码
编译出目标文件:
gcc -c -fpic xxx.c -> xxx.o
把目标文件打包成共享库:
gcc -shared x1.o x2.o … -o libxxx.so
-fpic编译出位置无关代码,在代码中使用相对地址,这样共享库就可以遇到内存的任何位置。

使用共享库
1、直接调用
gcc main.c libcalc.so
注意:需要设置共享的加载路径,LD_LIBRARY_PATH
2、通过设置LIBRARY_PATH环境变量来指定库的路径gcc main.c -lcalc 需要通过-l来指定库名
注意:如果静态库和共享库同时存在,优先使用共享库,通过-static可以指定使用静态库。
3、通过gcc -L参数来指定库的路径
gcc main.c -L./calc/ -lclac
4、动态加载共享库
#include <dlfcn.h>
void *dlopen(const char *filename, int flag);
功能:打开共享库
filename:共享库的路径
flag:打开方式
RTLD_LAZY:延迟加载,使用到共享库时再加载
RTLD_NOW:立即加载
返回值:成功返回共享库的句柄,失败返回NULL

void *dlsym(void *handle, const char *symbol);
功能:通过函数名在共享库中获取函数指针
handle:共享库的句柄
symbol:函数名
返回值:函数地址,失败返回NULL

char *dlerror(void);
功能:获取错误信息

int dlclose(void *handle);
功能:卸载共享库
注意:编译时添加-ldl参数

静态库与共享库的区别

调用静态库时,是把被调用的代码拷贝到可执行文件中。
优点:执行速度快
缺点:编译速度慢、编译结果大、不方便升级。

使用共享库时,调用者会记录被调用的代码在共享库中的位置,生成跳转指令,当执行可执行文件运行时,
操作系统会被他使用到的共享库一起加载,当执行到调用语句时跳转到共享库中执行被调用的代码
优点:方便升级维护、编译结果小、速度慢
缺点:执行速度慢

环境变量表

每个程序执行时都收到一张操作系统传递给的环境变量表,方便该程序了解当系统的环境配置,env命令可以在终端查看环境变量表。

环境变量表是一个以NULL结尾的字符指针数数组。
该表是系统环境变量的拷贝,程序对当前这张进行修改,并不影响制作系统。

char *getenv(const char *name);
功能:根据环境变量名获取环境变量的值

int putenv(char *string);
功能:name=value向环境变量表中添加环境变量,环境变量不存在则添加,存在则修改。
返回值:0表示成功,非零表示失败q
注意:不会把字符串拷贝到环境变量表中,而是把字符串地址存储到数组中。

int setenv(const char *name, const char *value, int overwrite);
功能:以name,value的形式向环境变量表添加环境变量,如果环境变量不存在则直接添加,如果存在则根据overwrite参数进行修改。
overwrite:
零 环境变量已经存在则不修改
非零 功能相当于putenv
返回值:0表示成功,非零表示失败

int unsetenv(const char *name);
功能:删除环境变量
返回值:0表示成功,非零表示失败

int clearenv(void);
功能:清空环境变量

定位头文件

头文件的三种定位方式:
1、#include “路径/xxx.h” 直接把路径写在代码中,但如果头文件路径发生变化,需要修改源代码。

2、gcc -I目录 在编译时指定加载头文件的路径。

3、设置C_INCLUDE_PATH环境变量,来添加头文件的查找路径。
打开配置文件:vim ~/.bashrc
在文件末尾添加一行内容:export export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/头文件路径
重新加载配置文件:source ~/.bashrc
env命令可以查看所有环境变量。
扩展:PATH环境变量代表是命令的查找路径,把.添加进去以后再执行程序就不需要./了。
注意:删除环境变量时需要退出终端,再重新打开

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值