宁波市高等级公路建设指挥部网站,房产网站制作流程,瑞安建设网站,网站链接结构有哪些目录
一、动/静态库的概念回顾#xff1a;
二、动态库与静态库的区别#xff1a;
三、静态库的创建与使用#xff1a;
1、Linux静态库命名规则#xff1a;
2、静态库的创建和使用#xff1a;
四、动态库的创建与使用#xff1a;
1、Linux动态库命名规则#xff1…目录
一、动/静态库的概念回顾
二、动态库与静态库的区别
三、静态库的创建与使用
1、Linux静态库命名规则
2、静态库的创建和使用
四、动态库的创建与使用
1、Linux动态库命名规则
2、动态库的创建和使用 一、动/静态库的概念回顾 从上一章节基础I/O中我们讲到库其实就是已经写好的、成熟的、可以直接使用的代码库里面封装了数据和函数可以直接提供给用户进行调用。
而所谓的静态、动态是指在链接阶段如何处理库链接成可执行文件。
编译过程 二、动态库与静态库的区别
静态库 静态库在链接阶段会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中通俗点就是静态库在编译的链接阶段与目标文件一起打包生成可执行文件成为可执行文件的一部分。所以当多个应用程序同时引用一个静态库函数时就会在内存中调用函数的多个副本大大增加可执行文件的体积其优点是节省编译时间。 动态库 动态库在程序编译时并不会被链接到目标代码中而是在程序运行是才被加载和链接。所以被调函数在内存中只有一个副本、可以实现进程之间资源的共享且动态库可以在程序运行期间释放动态库所占用的内存。 动态链接所调用的函数代码并不会拷贝到可执行文件中也就是说可执行文件与动态库是分开的只会在可执行文件中加入所调用函数的描述信息当程序装载进内存中运行时在OS的管理下会在程序与对应的动态库之间建立链接关系当要执行所调用动态库的函数时会根据链接产生重定位信息然后去执行执行动态库中对应的函数。
三、静态库的创建与使用
1、Linux静态库命名规则
Linux的静态库的命名规范为lib[xxx].a
lib为前缀中间的xxx为这个静态库的名字.a为拓展名例如一个名为test的静态库为libtest.a
2、静态库的创建和使用
前面说到静态库是在链接阶段将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。我们可以试想一下静态库会与汇编生成的目标文件一起链接为可执行文件那么静态库必定跟.o文件格式相似。其实一个静态库可以简单看成是一组目标文件.o/.obj文件的集合即很多目标文件经过压缩打包后形成的一个文件。
下面用一段简单的代码编译成静态库
函数声明: add.h
int add(int x, int y);函数定义: add.cpp
int add(int x, int y)
{return x y;
}
Linux下使用ar工具、Windows下vs使用lib.exe将目标文件压缩到一起并且对其进行编号和索引以便于查找和检索。
一般创建静态库的流程如下 通过上面的流程图可以看到我们要先把代码文件编译成目标文件.o
g -c add.cpp
然后通过ar工具将目标文件打包成.a静态库文件将add.o打包成libadd.a
ar -crv libadd.a add.o 静态库的使用
这里我们写一段使用库中函数的代码用来测试 Linux下使用静态库一般为 g Test.cpp -L ./ -l add 选项 -L表示要连接的库所在目录 -l指定链接时所需要的库去掉前缀lib和后缀如上就是libadd.a去掉前后缀 此时我们删掉静态库可以发现程序还是一样能正常运行因为静态库已经成为这个可执行文件的一部分了不需要依赖外界了如下图 四、动态库的创建与使用
1、Linux动态库命名规则
Linux的动态库的命名规范为lib[xxx].so
lib为前缀中间的xxx为此动态库的名字so为拓展名例如一个名为test的动态库为libtest.so
2、动态库的创建和使用
前面说到动态库在程序编译时并不会被连接到目标代码中而是在程序运行是才被载入。所以动态库只需要在内存中只存在一份拷贝即可就能有效避免静态库浪费空间的问题且对程序进行更新也只需要更新动态库增量更新即可。 针对于实际库文件每个共享库都有个特殊的名字soname。在程序启动后程序会通过这个名字来告诉动态加载器该载入哪个共享库。 在文件系统中soname仅是一个链接到实际动态库的链接。对于动态库而言每个库实际上都有另一个名字给编译器来用。它是一个指向实际库镜像文件的链接文件 (libsoname.so) 创建动态库文件这里我直接复用上面的代码
函数声明: add.h
int add(int x, int y);函数定义: add.cpp
int add(int x, int y)
{return x y;
} 生成动态库的命令为g -fPIC -shared -o libadd.so add.cpp 选项
-fPIC创建与地址无关的编译程序picposition independent code实现在多个应用程序间进行共享。
-shared指定生成动态链接库。(生成.o文件)
-o重命名将打包出的库文件命名成libadd.so
其实将整条命令拆分一下就是 g -fPIC -c add.cpp (生成.o文件) g -shared -o libadd.so add.o (生成.so库) 注意下面这张图的a.out并不是动态库生成的是上面静态库生成的。 动态库的使用Test.cpp代码还是和上面一样 g Test.cpp -L ./ -l add 引用动态库编译成可执行文件跟静态库的方式一样 但是此时我们运行生成的可执行文件会发现这样子会报错 这是因为编译器只会去库目录和环境变量中找动态库Linux环境下的库文件一般都放在 /lib 或者 /usr/lib 目录下所以我们得要让程序能找到动态库。 解决方法
1、将生成的动态库拷贝到 /usr/lib 或者 /lib 目录下
这种方法虽然简单直接但是不推荐用这种方法因为这会污染系统的库源 2、修改环境变量 LD_LIBRARY_PATH
环境变量 LD_LIBRARY_PATH是动态库的搜索路径一般情况下为空可执行文件运行时会去这个环境变量中搜索动态库路径但是注意新建终端或者重启就会失效 3、建立软链接
直接在lib或lib64目录下建立一个指向这个动态库的一个软链接推荐这种用法
对于32位程序一般会链接到 /usr/lib 中的库。而64位程序则会链接到 /usr/lib64 中的库。但也有例外情况例如如果64位系统上的某个64位程序需要向后兼容32位库它可能仍然会链接到 /usr/lib 中的库。 补充可以通过ldd 命令可以查看当前执行文件所链接的动态库 如果将对应需要的动态库删除的话那这里(红色框处)就会显示找不到库自然程序也就无法运行了
如下如果删除动态库程序就会无法运行 动态库更新
更新时只需更新动态库即可就不需要连同使用库的应用程序一起进行编译了如下更改了的逻辑变成-只需对动态库进行重新编译就可以实现程序更新了