Linux动静态库

动态库和静态库在链接时和可执行程序产生关联,静态库(.a)就是在编译链接时把需要的代码和数据拷贝到可执行程序,程序运行是不需要静态库。

而动态库(.so)是程序运行时才去链接动态库的代码,多个程序共享使用库的代码,把需要的代码和数据地址拷贝到程序当中。


 -c命令把源文件编译形成.o文件。 

-c是汇编生成二进制文件的过程。

三个文件都生成.o文件。

 

 把文件链接起来就能形成一个可执行程序。

下面这种之前的写法是把.c文件变成.o之后链接的,也需要走上面写法的步骤。 

 

 *.o把所有.o文件删除


把.o文件复制到上级文件中。

 但是在上级目录中编译main.c会报错

因为mian.c中包含了加和减的头文件

 把.h文件传到这个目录后-c编译就能过了。


如果我们不想给对方我们的源代码,给对方提供.o可重定位的二进制文件 ,让对方用对方的代码链接就行,未来可以提供.o(方法的实现)和.h(有什么方法)文件。

不提供原代码意思是没提供.c文件而是提供了.o目标文件

这大概就是库的思想。

为了避免要编译的.c文件过多,我们尝试将所有的".o"文件打包,给对方提供一个库文件即可。

这个"包"就是个库文件。

多个.o放进一个文件里,这个文件叫库。打包工具和打包方式不同分为静态库和动态库。

库的本质就是.o文件的集合。


  • 静态库和静态链接。

静态库打包

 表示libmymath.a是一个归档文件。

 删除库文件。

 发布

把库文件放进一个目录下。

 这个命令就是对库的打包。


 解压

 所谓的安装就是把可执行程序拷贝到系统能找到的目录下。


当我们有库后,对main.c进行编译,发现它找不到头文件,因为编译时头文件在当前目录或指定路径下 寻找,而这里头文件在目录下太深,就找不到了。

 我们可以给gcc指定搜索路径。

但这样指定后还会报错,是链接错误, 因为只指定了头文件,没指定库文件。

但指定后还是不行。因为链接库,必须指定库名称。

 

 之前写代码时没指明库名称,之前我们用的c/c++的标准库,gcc和g++默认就能找到。

-I代表头文件路径,-L代表库文件路径,-l代表要链接的库文件,名称。这些命令和后面代码之间有没有空格都行。

 注意,库名称不包括前缀和后缀。


形参可执行程序可能不仅仅链接一个库.

gcc默认动态链接(建议选项),对于特定的库,究竟是动还是静取决与提供的是动态库还是静态库。

只有动态库时是动态链接,只有静态库时是静态链接,如果动静态都有,那么动态库时动态链接,静态库是静态链接,但整体体现为动态链接。

安装静态库。 

用第三方库不能直接编译

要指定编译哪个库

  •  生成动态库

生成动态库也是把所有源文件变成.o文件,多了一个命令。

 fPIC:生成.o文件时产生位置无关码。

动态库打包命令:


 直接编译,链接依然找不到头文件。

 -I搜索头文件,-L搜索库文件,-l告诉编译器要链接库的名称。

发生报错。 这就是动态库和静态库的不同了。 

 库文件,路径和名称上述代码中是给gcc看的,当程序编译完,和gcc就无关了。

程序运行起来,操作系统和shell也需要知道库在哪。而动态库还没在操作系统路径下,操作系统无法找到。

将库路径添加到加载库的环境变量中可以让操作系统找到库。

这样,这个环境变量就包含了这个库。

也就能运行了。

 而当我们重新打开一个窗口,再次运行,就又不能运行了。

因为自己定义的环境变量一般只在本次登陆有效。


这个路径有各种配置文件。

动态库在进行搜索时,可以采用自己定义conf配置文件的方式,让操作系统找到动态库。

把动态库路径写到任意名称的配置文件(这个配置文件在上图中的路径中)中。再在这个路径下执行ldconfig命令。这样就能永久执行这个动态库路径了。

但把写入路径的配置文件删掉,使用这个动态库的程序就不能运行了。


创建一个动态库的软链接。也可以运行。

 

 说明搜索动态库时默认在当前路径下搜索。


还有一个方式,这样建立软链接。

把动态库建立在系统路径下。

软链接文件是红框部分,软链接文件的路径是这里的全部蓝色部分 ,通过路径拿到这个软链接文件。

我们可以像这样安装第三方库。


  • 动静态库的加载。

静态库

把静态库的代码拷贝到可执行程序中,拷贝到哪里?

拷贝到代码段。

我们的程序在编译时,已经以虚拟地址的方式,帮我们把我们的程序编译好。

就是说,我们的程序在没有被加载到内存时,已经有代码段,全局数据区都已经有了。

未来这部分代码,必须通过相对确定的地址位置来进行访问。

动态库

动态库加载是把动态库中指定函数的地址,写入到可执行程序中。

动态库中函数采用起始地址加偏移量的方式。而传给可执行程序只传偏移量。

执行程序时,操作系统通过页表,编译时能识别出内存中可执行程序的这个代码的地址并不存在。识别出是个外部地址。能识别出需要访问的库。操作系统就先不执行这个代码了。

就开始加载库,在磁盘中找动态库,并加载。

把库提供页表映射到进程的共享区(在堆和栈之间)中。一旦映射就知道了这个库的虚拟地址。

因为要调用的函数,在库中的偏移量已经填写好,这样就能找到要调用的函数了。

产生与位置无关码,决定了库中的函数采用相对编址的方式。

动态库中应该程序多次调用库中的函数,只拷贝进内存中一次库。而静态库每次调用函数都会被拷贝进内存中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南种北李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值