linux复习
1.nm命令
用来查看库文件(.a,.lib),目标文件和可执行文件的符号表 常用参数nm -n 按照地址对符号表进行排序
2.判断大小端
小端地址小端存放为小端,小端地址大端存放为大端 例1
uint32 check_little_endian() { int i = 0x12345678; char *p = (char *)&i; return (*p == 0x78); }
p指向i的低地址,当p指向的值为0x78说明低地址存放低字节,说明是小端;当p指向0x12说明低地址存放高字节是大端
3.库文件
-
库是一种组件技术。
-
库里封装了数据和函数,提供给用户程序调用。
-
库只执行到第三阶段编译,没有用链接
-
库的使用可以是程序模块化,提高程序的编译速度,实现代码复用
linux的库
linux系统通常把库文件存放在/usr/lib或/lib目录下 linux库文件名组成:前缀lib+库名+后缀
动态库和静态库的区别
1.载入顺序不同
静态库的代码在编译是就拷贝到应用程序中,因此当多个应用程序同时引用一个静态库函数时,内存中将会调用函数的多个副本。其优点是节省编译时间。 动态库是在程序开始运行后且调用库函数时才被载入,被调函数在内存中只有一个副本,并且动态库可以在程序运行期间释放动态库所占用的内存。
2.大小与共享的差异
静态链接就是在程序编译的时候被加载进来,这样的可执行文件会比较大一些,不能共享;动态链接是在程序执行到的时候加载进来,可以共享。
3.库函数调用的差异
静态链接是指把要调用的函数或者过程链接到可执行文件,称为可执行文件的一部分。 动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中,而是仅仅在其中加入了所调用函数的描述信息(往往是重定位信息)。仅当应用程序被装入内存开始运行时,在linux的管理下,才在应用程序与相应的so之间建立链接。当要指向所调用的函数时,根据链接产生的重定位信息,才转去执行动态库中相应的函数代码。
静态库的创建和使用
1. 创建静态库的步骤:
1.在一个头文件中声明静态库所导出的函数 2.在一个源文件中实现静态库所导出的函数 3.编译源文件,生成可执行代码(没有连接) 4.将可执行代码所在目标文件加入到某个静态库中,并将静态库拷贝到系统默认的存放库目录下(/usr/lib或/lib)。
2.生成静态库的实例
(1)头文件mylib.h —— 声明静态库所导出的函数
#ifndef _mylib_H_ //如果没有定义此标识符,编码以下程序 #define _mylib_H_ 1 void welcome(); void outstring (const char * str); #endif
(2) 对应于头文件的源文件mylib.c —— 实现静态库所导出的函数
#include “mylib.h” #include <stdio.h> void welcome() { printf (“welcome to libmylib\n”); } void outstring(const char * str) { if (str !=NULL) printf (“%s”,str); }
(3)编译mylib.c生成目标文件: gcc –o mylib.o –c mylib.c 注: -c是只编译而不生成可执行文件,-o指定文件名
(4)将目标文件加入到静态库中,静态库为libmylib.a ar rcs libmylib.a mylib.o
参数说明: r —在库中加入新成员文件,如果要加入的成员文件存在,则替换之默认情况下,新的成员文件增加在库的结尾处 c 创建一个库 s 无论ar命令是否修改了库内容,都强制重新生成库符号表
(5)将静态库拷贝到 linux 的库目录(/usr/lib或/lib)下 cp libmylib.a /usr/lib/libmylib.a
到这里静态库就生成完了,下面我们尝试用一个程序链接它。
3. 调用静态库的测试程序
简而言之就是:用一个.c源文件在编译时做静态链接
(一)调用静态库的测试程序:test.c
#include “mylib.h” #include <stdio.h> int main() { printf (“create and use library:\n”); welcome(); //静态库中的函数原型 outstring(“It’s successful\n”); //静态库中的函数原型 }
(二)编译使用了库函数的程序 gcc –o test test.c –lmylib
参数说明: (1)选项l为链接选项说明在链接时就将静态库链接至源程序中 (2)在Linux中约定所有库都以前缀lib开始,静态库以.a结尾,动态库以.so结尾,在编译时,无需带上前缀(lib)和后缀(.a)。
参考源链接
原文链接:详解Linux下静态库/动态库的生成和使用(含代码示例和操作流程)&&动态库和静态库的区别_生成静态库的过程及作用-CSDN博客
动态库的创建和使用
1.确定库中函数的功能、接口 2.编写库源码hello.c bye.c
#include <stdio.h> void hello(void) { printf(“hello world\n”); return; }
3.编译生成目标文件 gcc -c -fPIC hello.c bye.c -Wall
4.创建共享库common gcc -shared -o libcommon.so.1 hello.o bye.o 5.为共享库文件创建连接文件 ln -s libcommon.so.1 libcommon.so 6.链接共享库
编写应用程序test.c
#include <stdio.h> #include “common.h” int main() { hello(); bye(); return 0; }
7.编译test.c并链接共享库libcommon.so gcc -o test test.c -L. -lcommon
8.执行程序
$ ./test ./test: error while loading shared libraries: libcommon.so cannot open shared object file : No such file or directory
9.添加共享库的加载路径
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. $ ./test hello world bye!
10.如何找到共享库
为了让系统能找到要加载的共享库,有三种方法 :
-
把库拷贝到/usr/lib和/lib目录下
-
在LD_LIBRARY_PATH环境变量中添加库所在路径
-
添加/etc/ld.so.conf.d/*.conf文件,执行ldconfig刷新