一些关于Linux库的知识

1.一些文件后缀跟参数

  • 文件后缀
    .h 头文件
    .gch 头文件的编译结果,一般不要保留。
    .c 源文件
    .i 预处理文件
    .s 汇编文件
    .o 目标文件
    .a 静态库文件
    .so 共享库文件

  • 文件后缀**
    .h 头文件
    .gch 头文件的编译结果,一般不要保留。
    .c 源文件
    .i 预处理文件
    .s 汇编文件
    .o 目标文件
    .a 静态库文件
    .so 共享库文件

  • -参数
    -E 预处理
    -S 汇编
    -c 编译(只生成目标文件)
    -o 指定编译结果的名字
    -Wall 产生尽可能多的警告
    -Werror 把警告当作错误处理
    -x 指定编译的语言
    -g 生成调试信息
    -On 优化等级
    -D 编译时定义宏
    -l 链接里加库
    -I 指定头文件的查找路径,配置环境变量
    1、打开 vim ~/.bashrc
    2、在文件末尾,添加一行 export C_INCLUDE_PATH=$C_INCLUDE_PATH:NEW_PATH
    3、重新加载配置文件 source ~/.bashrc
    注意:如果要删除环境变量需要在~/.bashrc文件中删除环境变量后,退出终端重新打开。

     	考题1:#include <> / #include "" 区别?
     	考题2:头文件中可以编写哪些内容?
     	考题3:头文件的作用?
     		1、说明对应的.c文件的内容有哪些(声明函数、全局变量)。
     		2、定义结构、联合、枚举、宏。
     		3、类型重定义。
     		虽然函数可以隐式声明,但并不一定准确,而且非常有可能造成严重错误。
    
  • 预处理指令

    #include 文件包含,区别分""和<>的区别
    #define 定义宏常量或或函数
    # 把标识符转换成字符串
    ## 合并标识符
    #undef 删除宏
    #line 指定当前行的行号
    #if
    #ifndef
    #ifdef
    #elif
    #endif
    #error 在编译期间产生错误
    #warning 在编译期间产生警告
    #pragma
    #pragma GCC dependency 用于监控文件,防止所依赖的文件,修改后而不知道。
    #pragma GCC poison 用于禁用某些标识符
    #pragma pack(n) 设置结构、联合的补齐和对齐字节数
    n的值必须比默认值的要小
    对齐边界必须是 2 的较小次方

2.库

库就目标文件的集合,我们把不需要升级更新维护的代码打包合并在一起方便使用,也可以对源代码进行保密。

静态库在使用时是把被调用的代码复制到调用模块中,然后在执行程序时,静态库就不需要了。

静态库的执行速度快,但占用空间大,当库中的内容发生变化时,需要重新编译出新的程序,因此不能轻易修改库中的内容。

而共享库只是在调用模块中嵌入调用代码的在库的相对位置的地址,当执行程序时,共享库会的程序一起加载到内存中,当执行到调用共享库中代码的指令时跳转到共享中执行,执行完毕后在跳转回来。

占用空间小,方便更将新(共享库发生变化后,程序不需要再次编译),相对于静态库执行效率略低。

静态库的扩展名为.a,共享库(动态库)的扩展名为.so

**

3.静态库

**

1. 1、创建静态库

编写源代码:vi .c/.h
编译源代码:gcc -c xxx.c -> xxx.o
打包生成静态库:ar -r libxxx.a x1.o x2.o …
ar命令的一些参数:
-r 把目标文件添加到静态库中,已经存在的更新
-q 将目标文件追加到静态库的末尾
-d 从静态库中删除目标文件
-t 显示静态库中有哪些目标文件
-x 把静态库拆分成目标文件
**

1. 2、调用静态库

**
直接调用:调用者要和库在同一路径下
gcc main.c libxxx.a
设置环境变量:设置方法与C_INCLUDE_PATH类似
1.打开 vim ~/.bashrc 文件
2.在文件末尾添加一行
export LIBRARY_PATH=$LIBRARY_PATH:库文件的路径
3.重新加载配置文件 source ~/.bashrc
4.编译时要指定库名
gcc main.c -lmath
设置编译参数:-L路径
gcc main.c -L路径 -lmath

**

  1. 3、运行

**

在编译时已经把被函数的二进制复制到可执行文件中了,在执行时不再需要静态库文件。

**

4.共享库

**

2. 1、创建共享库

编写源代码:vi .c/.h
编译出位置无关目标文件:
gcc -c -fpic xxx.c -> xxx.o
链接生成共享库:
gcc -shared x1.o x2.o x3.0 … -o libxxx.so

2. 2、调用共享库

直接调用:调用者要和库在同一路径下
gcc main.c libxxx.so
设置环境变量:设置方法与C_INCLUDE_PATH类似
1.打开 vim ~/.bashrc 文件
2.在文件末尾添加一行
export LIBRARY_PATH=$LIBRARY_PATH:库文件的路径
3.重新加载配置文件 source ~/.bashrc
4.编译时要指定库名
gcc main.c -lmath
设置编译参数:-L路径
gcc main.c -L路径 -lmath

2. 3、运行

在使用共享库时,调用者只是记录了被代码在库的位置,因此在执行时需要共享库同时被加载。
操作系统会根据LD_LIBRARY_PATH环境变量的设置来加载共享库。

**

5.动态加载共享库

**
#include <dlfcn.h>

1. 加载共享库

void *dlopen(const char *filename, int flag);
filename:共享库的库名,或路径
flag:
RTLD_LAZY 使用时才加载
RTLD_NOW 立即加载
返回值:共享库的句柄(类似文件指针)

2. 获取标识符地址并使

void *dlsym(void *handle, const char *symbol);
handle:共享库的句柄
symbol:标识符的名字
返回值:标识符在共享库中的位置(地址,可以解引用,或跳转过去)。
**

3、卸载共享库

**
int dlclose(void *handle);
handle:共享库的句柄
返回值:成功返回0,失败返回-1

**

4、获取错误信息

**
char *dlerror(void);
返回值:会把在使用共享库的过程中出现的错误,以字符串形式返回

6.辅助工具

nm:查看目标文件、可执行文件、静态库、共享库的中的符号列表
ldd:查看可执行程序所依赖的共享库有哪些
strip:减肥,去除掉目标文件、可执行文件、静态库和共享库中的符号列表、调试信息。
objdump 显示二进制模块的反汇编信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值