文章目录

  • 回顾基础
  • 学会打包自己的库并使用
  • 静态库
    • 打包库
    • 第三方库的使用
  • 动态库
    • 打包库
    • 第三方库的使用
  • 动态库加载以及周边问题

回顾基础

这篇文章主要对动静态库进行进一步的学习,关于动静态库的一些基础知识,请点击这篇文章的链接:【Linux】初识动静态库

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
  • 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码。
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)。
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。

1.我们在vs编译器下安装开发环境——本质就是安装编译器软件,安装要开发的语言配套的库和头文件。

2.我们在使用编译器的时候,都会有语法的自动提醒功能,有这个提醒功能的前提是要先包含对应的头文件的,所以语法提醒的本质就是编译器或者编辑器,会自动根据用户输入的内容,不断的在被包含的头文件中进行搜索,自动提醒功能是依赖头文件的。

3.系统已经预装了C/C++的头文件和库文件,头文件提供方法说明,库才提供方法实现,头和库是有对应关系的,是要组合在一起使用的。

4.头文件是在预处理的阶段就引入的,链接的本质实际是在链接库。

学会打包自己的库并使用

静态库

打包库

这里我们用一个简单的加减函数来示范,我们先创建以下几个文件,并在mysub,myadd文件中实现对应的功能。(简单的加减函数这里就不赘述了)

当别入需要使用我们实现的代码功能时,我们不可能把myadd.c,mysub.c源代码直接交出去,因为这就暴露了我们代码的实现细节,所以我们往往将.c .h文件打包成一个库(二进制文件),再给别人。

所以我们这里又创建了一个目录otherPerson代表需要用我们打包的库的其他人。

开始演示:





原因:当我们有了一个库,接下来,要将库引入我们的项目,必须让编译器找到头文件+库文件。

看!现在“别人”通过库文件和头文件就可以成功运行程序了。

步骤:

  1. 先准备好.h和.c文件,然后用gcc-c选项生成.o目标文件;
  2. 命令ar -rc libmymath.a *.o生成静态库,ar是gnu归档工具,rc表示(replace and create);
  3. 查看静态库的目录列表:ar -tv libmymath.a,t:列出静态库中的文件,v:详细信息;
  4. 运行程序命令:gcc -o mytest main.c -L. -lmymath,-L:指定库路径,-l:指定库名
  5. 测试目标文件生成后,静态库删掉,程序照样可以运行。

但实际上一般是打包头文件和库文件给其他人的:

第三方库的使用

1.需要指定的头文件和库文件;
2. 如果没有默认安装到系统gcc,g++默认的搜索路径下,用户必须指明对应的选项,告知编译器头文件在哪里,库文件在哪里,库文件具体是谁。
3. 将我们下载下来的库和头文件,拷贝到系统默认路径下——这个行为就是在Linux下安装库。对任何软件而言,安装和卸载的本质就是拷贝到系统的特定路径。


4. 如果我们按安装的是第三方的(1,2语言,操作系统接口)库,我们要正常使用,即便是已经全部安装到了系统中,gcc/g++必须用-l指明具体库的名称。
5. 无论是从网络中直接下好的库,或者源代码(可能会提供内置编译方法)——必须有make install安装的命令,实际上就是拷贝安装到系统中,所以我们安装大部分命令,库等等,都是需要sudo或者超级用户操作(因为需要访问系统)。

将第三方库安装到系统中:(还是以上述为例子)

a.提取权限将我们include目录下的所有头文件拷贝到系统头文件/usr/include/中:
sudo cp -rf include/* /usr/include/

b.提取权限将我们lib目录下的静态库拷贝到系统的库/lib64中:
sudo cp lib/* /lib64

c.这时就算我们删除了lib和include目录,只有main.c文件,也能成功生成可执行程序,正确编译:
gcc -o mytest main.c -lmymath

云服务器一般都只会提供动态库,下面是安装静态库的命令:

sudo yum install -y glibc-static
sudo yum install -y libstdc++-static

动态库

打包库

还是以上面的加减函数为例:

编译生成.o目标文件:
fPIC:产生位置无关码(position independent code)

进行打包,动态库的打包就不是用ar了,而是还是用gcc,用法如下:
shared: 表示生成共享库格式
.o文件打包成动态库:

还是一样的准备两个自己的目录:include和lib,分别装填自己的头文件和动态库。

将头文件include和lib库文件打包:

第三方库的使用

将mylib中我们已创建好的包mymath.tgz传给“其他人”,本质是拷贝到指定目录下的一个过程。


报的错是找不到动态库,但是我们已经采用上面讲到过的方法,告诉了编译器头文件的位置-I和库的位置-L,还有文件名-l,但是竟然没有成功!为什么呢?

那是因为,运行的时候.so文件并没有在系统的默认路径下,所以操作系统依旧找不到,静态库能找到的原因是,静态库的链接原则是将用户使用的二进制代码拷贝到了目标可执行程序中,但是动态库的链接原则不是这样的。

那么运行时,OS是如何查找动态库?方法如下:

方法一:配置环境变量

环境变量:LD_LIBRARY_PATH(临时方案,因为环境变量只在当前会话有效,退出了就没了)

echo $LD_LIBRARY_PATH //查看环境变量

方法二:软链接方案

我们在/lib64下建立了一个软链接,指向libmymath.so目标文件的所在路径。



方法三:配置文件方案

1.所要配置的文件名称:/etc/ld.so.conf.d/
2.获取权限在该配置文件下创建一个你的文件,如:sudo touch /etc/ld.so.conf.d/nan_test.conf
3.查看是否创建成功:ls /etc/ld.so.conf.d/
4.查看所需第三方动态库所在路径,以上述例子为例,lib动态库的路径是:
/home/nan/linux-learning/基础IO/动态库/otherPerson/lib
5.获取权限vim打开你刚刚在配置文件下创建的文件:sudo vim /etc/ld.so.conf.d/nan_test.conf将你刚刚获得的动态库路径添加进去,并保存。
6.ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新:sudo ldconfig
7.查看动态库是否添加成功:ldd mytest(可执行程序)
8.最后执行程序,over!!!

动态库加载以及周边问题

静态链接的加载:静态链接形成的可执行程序,本身就有静态库中对应方法的实现,但是非常占用资源!(可执行程序变大加载占用内存,下载周期变长,占用网络资源)

动态链接的加载:将可执行程序中的外部符号,替换成为库中的具体地址。只要我们把库加载到内存,映射到进程的虚拟地址空间之后,我们的代码执行库中的方法,在自己的地址空间内进行函数跳转即可。

库中地址的理解

动态库面临一个问题:不同的进程,运行程度不同,需要使用的第三方库是不同的,每一个进程的共享空间(栈和堆之间有一块共享区)中空闲位置是不确定的!那么动态库和静态库加载的地址是怎么处理的呢?

答:由编译器确定,编译器确定地址分为两种形式:
1.根据当前PC+偏移量确定地址(动态库采用)
2.直接用链接地址(通过链接脚本指定)(静态库采用)

区别就是:代码运行的时候,是否和所处内存地址有关。
位置有关码要求运行是代码必须在特定位置;
位置无关码则没有要求,动态库中的所有地址,都是相对于当前PC值的偏移量,默认地址从0地址开始。动态库,在进程的地址空间中,随便加载,与我们加载到地址空间的什么位置,就毫无关系了,动态库中地址,都是偏移量。

这也就是为什么,上面我们在制作动态库的时候,要加上-fPIC选项:

位置无关码和位置有关码可以用下面一个生活的例子感性理解一下:

1.我在这条路的60米处左右——绝对编址
2.我在这条路的一棵大树左边,大约距离20米——相对编址

【Linux】动态库与静态库,如何打包库,如何使用第三方库相关推荐

  1. Linux 动态链接和静态链接简析(库名与库文件名)

    原文请见 Linux动态链接和静态链接简析 0. 库名与真正的库文件名 就拿数学库来说,他的库名是 m,他的库文件名是libm.so,很容易看出,把库文件名的头 lib 和尾.so去掉就是库名.(gc ...

  2. pip安装更新、第三方库对应的python解释器版本、pip安装第三方库,压缩包离线安装,pycharm快捷安装及pycharm中terminal的使用,timeout超时报错

    文章有点长,但是很详细,还望大家耐心看 之前在安装python的文章中已经给大家配置了pip环境变量(不了解的点这里去看看),这里就能直接在cmd窗口,不用切换路径,就能使用pip了. 首先 使用pi ...

  3. python调用第三方库需要联网吗_离线环境安装python第三方库

    0. 概述 这个方法是使用pip换本地源下载依赖库的方式执行的,分为以下几个步骤 1. 安装/更新pip到最新版本. 2. 在联网环境下载依赖库的包和建立requirement.txt. 3. 将上一 ...

  4. 艺赛旗RPA 第三方库系列(一):如何调用 Python 第三方库

    目前艺赛旗RPA已经更新到8.0版本,可以让所有用户免费下载试用http://www.i-search.com.cn/index.html?from=line1 (复制链接下载) 当你需要调用使用 p ...

  5. python json库安装_【Python基础】安装python第三方库

    pip命令行安装(推荐) 打开cmd命令行 安装需要的第三方库如:pip install numpy 在安装python的相关模块和库时,我们一般使用"pip install 模块名&quo ...

  6. spacy库的安装与使用_Python 安装、使用第三方库的一些经验

    (一)更改pip源至国内镜像 清华大学的pip源像 https://pypi.tuna.tsinghua.edu.cn/simple 临时使用: 可以在使用pip的时候加参数 -i https://p ...

  7. 下面不属于python第三方库的安装方法的是-关于python中第三方库安装方法和问题解决...

    一.安装方法 方法一: 1.管理员身份启动命令行(运行--->cmd) 2.pip install 库的绝对路径和库的详细名称 :或者运用cd命令跳转到下载好的库所在的位置然后pip insta ...

  8. python中安装一个第三方库的命令格式是-PyCharm 如何安装python第三方库及插件

    一.如何安装python第三方库: 1.有一个专门可下载安装第三方库的网址: http://www.lfd.uci.edu/~gohlke/pythonlibs/ Ctrl+f 搜索要下载的第三方库, ...

  9. python安装成功第三方库但import出问题_解析pip安装第三方库但PyCharm中却无法识别的问题及PyCharm安装第三方库的方法教程...

    一.问题具体描述: 在cmd控制台 pip install xxxx 后并显示安装成功后,并且尝试用cmd 的python 中import xxxx ,没有显示异常,说明这个库是安装成功了的.(这里以 ...

  10. c调用python第三方库_c/c++调用python程序且含tensorflow第三方库

    对于纯python程序而言,用c程序来调用是比较适合的,如果python程序中包含了其他第三方库,则调用极可能出错,且不易查明原因.如笔者曾用c程序调用包含tensorflow的python程序,有的 ...

最新文章

  1. [恩难到了]陨石的秘密
  2. Solaris 常用命令
  3. 进栈顺序为abcd则出栈顺序为_线性表之顺序表示
  4. Lua 文件 I/O
  5. 基于python技术的自动化运维是干嘛的_《Python自动化运维 技术与最佳实践》.pdf...
  6. ubuntu linux root,Ubuntu 中的 root 用户:你应该知道的重要事情 | Linux 中国
  7. P2498 [SDOI2012]拯救小云公主
  8. C#LeetCode刷题之#26-删除排序数组中的重复项(Remove Duplicates from Sorted Array)
  9. 被问到TCP的可靠传输和提高网络利用率?
  10. Zend 创始人欲创建 PHP 方言,暂名为 P++;鸿蒙 OS 面世;中国首个开源协议诞生 | 开发者周刊...
  11. R语言——相关系数图
  12. gtj2018如何生成工程量报表_工程量清单计价规范2018
  13. 下跌趋势底背驰的几种经典信号
  14. 计算机专业初学者推荐书籍
  15. Arduino UNO控制带AB相磁通量式编码器电动推杆(测试阻尼)实录(L289N电机驱动)
  16. matlab声音处理
  17. 哈工大深圳计算机学院蔡聪怀,哈工大(深圳)计算机学院第一届光熙杯篮球赛圆满落幕...
  18. C# 可为 null 的类型
  19. 中国主导的.chn物联网域名首登世界舞台
  20. asterisk对接不知名语音网关

热门文章

  1. 【OpenStack头道鲜】春风十里,不如听君一席,康大厨私人课堂开讲啦!
  2. 位运算符:按位与(),按位或(|),按位异或(^),取反(~)左移()和右移()
  3. 中国最好听的十个姓氏
  4. dhcp服务器设置自动,路由器DHCP服务器怎样设置
  5. Ip网络技术组建--hybrid混合接口的简单配置例子
  6. Web前端学习day01(HTML)
  7. 字幕文件SRT转VTT格式(Java版)
  8. C语言编程歌咏比赛,斗志昂扬展风采 团结奋进谱新篇 ——记七年级c部队列队形歌咏比赛...
  9. 注册表-各种功能-隐藏IE、隐藏硬盘、禁用硬件
  10. webgl入门到成仙【入门-04wegbl的实际绘图思路】