Linux中的动态库与静态库

这篇具有很好参考价值的文章主要介绍了Linux中的动态库与静态库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

软链接与硬链接

软链接

当我们不在本地路径下运行时,运行目标二进制文件一般要写明该程序路径.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
但是这样运行对于路径较为复杂的程序极为耗费时间,为了简便操作,我们可以将该可执行程序的路径设置为软链接.此时的软链接一般也可认为是windows可执行程序的快捷方式.

创建软链接命令如下:

[yzh@VM-4-5-centos ~]$ ln -s /home/yzh/my.exe mysoft

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
注意:
创建软链接不能将可执行程序的路径写错了,不然运行该程序会出错.

硬链接

硬链接指在指定的目录下,建立文件名与目标inode文件的映射关系,一般默认为"取别名".

创建硬链接命令如下:

[yzh@VM-4-5-centos ~]$ ln /home/yzh/my.exe myhard

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

硬链接的用途

我们知道,inode中还有一个引用计数,它代表文件名与目标文件关联的个数.

  • 当我们创建一个硬链接,代表多了一个文件名与目标文件相关联,引用计数+1.
  • 当我们删除一个硬链接,代表少了一个文件名与目标文件相关联,引用计数-1.
  • 当引用计数减少为0时,代表没有文件名与目标文件相关联,进而代表该文件被真正删除.

删除链接关系命令:

[yzh@VM-4-5-centos ~]$ unlink myhard

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

延申问题

当我们创建一个空目录时,为什么该文件的引用计数为2呢?
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
因为自身的目录名与自身内部的 " . " ,都和同一个文件的inode具有映射关系.其中" . " 也代表着当前目录(也就是我们所在的目录).
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
再比如: 当我们在ceshi目录内创建一个ceshi1目录,进入该目录,使用ll -ail 目录查看,发现 该目录下的 "…“与ceshi目录的inode相同,说明”…"与ceshi目录也建立了映射关系.其中 "…"也代表着上一级目录.

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
所以,我们可以通过目标目录的引用计数-2(自身对应关系以及下一级目录下的 “.”),来判断该目录中所存在的下一级目录个数了(也代表着下一级目录中"…"的个数).

软硬来链接的区别

当我们查看创建的软硬链接,区别如下:

  • 软链接有独立的inode,说明软链接是一个独立的文件.
  • 硬链接没有独立的inode,说明硬链接不是一个独立的文件.
    Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

动态库与静态库

为了便于理解,我们创建了两个源文件与两个头文件,这些文件只为用以动静态库的相关操作.

mymath.c

累加到目标值.

#include "mymath.h"                                                                                            
int addToTarget( int form,int to )
 {
           int sum = 0;
 
           for( int i = form; i <= to; ++i )
            {
              sum += i;
            }
            return sum;
 }

mymath.h

 #pragma once
 #incldue <stdio.h>
 extern int addToTarget( int from, int to );

myprint.c

打印所给字符串以及时间戳.

#include "myprint.h"
void Print( const char* str )
{
   print("%s[%d]\n",str,(int)time(NULL));
}

myprint.h

#pragma once
#include <time.h>
extern void Print( const char* str);

main.c

调用myprint以及mymath相关库.

#include "myprint.h"                                                                                                #include "mymath.h"
int main()
  {
    Print("hello world\n");
    int res = addToTarget(1,100);
    printf("%d\n",res);
    return 0; 
 }

静态库

生成静态库

1.将所有源文件生成二进制文件.(不可执行).
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

2.使用rc命令,将这些二进制文件统一打包为静态库.

  • -r(replace): 如果创建的目标文件与静态库文件名相同,则将新的静态库文件替换掉重名的静态库文件.
  • -c(create): 创建静态库.
    Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
    3:将静态库中头文件与静态库统一放在指定目录中.
    Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

当然,为了简便以上操作,我们也可以采用使用Makefile统一生成.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
使用make,makeoutput命令同意生成并打包静态库.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

静态库的使用

方法一: 利用sudo cp命令分别将头文件复制在: /usr/include ,静态库文件复制: /lib64.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
但是使用gcc命令编译链接成打可执行程序时,需要指明编译的库.(库名去点前后缀即可) 例如: libhello.a --> hello.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
方法二:直接指明头文件,静态库文件的路径,并让编译器在指定路径下搜索.
编译命令如下:

gcc main.c -I ./output/include/ -L ./output/lib -lhello
  • -I: 表示指明头文件搜索路径.
  • -L: 表示指明库文件搜索路径
    Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

动态库

动态库的生成

方法一:

第一步:先将源文件统一编译为二进制文件(不可执行).

gcc -fPIC -c mymath.c -o mymath.o -std=c99
gcc -fPIC -c myprint.c -o myprint.o -std=c99

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
第二步: 使用gcc -shared命令所有目标文件打包生成动态库库

gcc -shared myprint.o mymath.o -o libhello.so

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

第三步: 将头文件与静态库统一放在指定目录中

我们选择将.h头文件放在output目录下的include中,将动态库.so文件放在include目录下的lib目录中.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
方法二: 使用Makefile统一打包生成.

我们将打包生成动静态库的所有命令写入Makefile中,使用Makefile命令统生成动静态库.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

动态库的使用

与动态库的使用不同的是,我们使用gcc -I -L -l编译链接产生的可执行程序不可以直接运行.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
原因:我们在gcc 使用 -I -L 表明动态库的路径时,是对gcc编译器说的,当我们要运行加载程序的时候,此时已经生成了可执行程序,跟gcc没有任何关系,但是要运行时,进程需要通过->虚拟地址空间->页表映射去寻找动态库的位置,所以我们要对Linux系统表明动态库的位置.,静态库不需要将库的地址告诉操作系统是因为静态库在加载的时候已经将代码加载到内存中了,不需要再去与操作系统建立映射关系查找.

方法一: 增加环境变量

由于LD_LIBRARY_PATH是进程运行动态库时所要搜索的路径,我们需要将动态库的路径添加到LD_LIBRARY_PATH环境变量即可.

在LD_LIBRARY_PATH 环境变量中使用export加动态库的绝对路径,使用达echo命令查看环境变量是否成功添加.

[yzh@VM-4-5-centos userlib]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/yzh/userlib/output.lib

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

方法二: 配置 /etc/ld.so.conf,d/ 文件

第一步: 在/etc/ld.so.conf,d/目录中创建一个文件(后缀一定要是.conf)

[yzh@VM-4-5-centos userlib]$ sudo vim /etc/ld.so.conf.d/yzh.conf

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
在该文件中加入动态库的路径.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
之后再使用 sudo ldconfig命令将/etc/ld.so.conf.d/下的目录文件更新就可以了.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
方法三: 设置软连接

将动态库的路径设置为路径为 /lib64/下的软链接,在设置软硬接中最好表明的是动态库的绝对路径,否则系统系统会找不到动态库。

[yzh@VM-4-5-centos userlib]$ sudo ln -s /home/yzh/userlib/output/lib/libhello.so /lib64/libhello.so

Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器
此时,我们使用 ls /lib64 查看软链接是否建立.
Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器

动静态库的区别

  • 静态库使用时是将可执行程序加载到内存中后通过页表映射到地址空间的代码区中,并且每一个进程运行该程序都会将该程序反复加载到内存中,极大浪费了内存空间.

  • 动态库可以和可执行程序进行分批加载,当进程运行到可执行程序中的动态库时,进程会将动态库加载到内存中,内存通过页表进行映射到地址空间中栈堆之间的共享区,当进程执行到动态库时,会从代码区跳转到共享区执行,当有多个进程时运行该可执行程序的动态库时,此时加载到内存中的动态库共享到每个进程,所以动态库也称为共享库.
    Linux中的动态库与静态库,Linux操作系统,linux,运维,服务器文章来源地址https://www.toymoban.com/news/detail-655426.html

到了这里,关于Linux中的动态库与静态库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux:动态库与静态库】

    静态库( .a ):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。 动态库( .so ):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表

    2024年02月06日
    浏览(39)
  • VS2019静态库与动态库入门操作指南

    源代码的二进制文件; 分为动态编译与静态编译; 1)区别 (1)动态编译不便于发布,静态编译便于发布; (2)动态编译生成的可执行文件体积较小,静态生成的可执行文件体积较大。 ​ Windows中静态库后缀为.lib 动态库后缀为.dll ​ Linux中静态库后缀为.a 动态库后缀为.

    2024年02月06日
    浏览(39)
  • 【Linux】静态库与动态库制作及运行原理

    Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。 先来总体描述下静态库与动态库的区别. 静态库是将头文件总体复制到可执行文件当中 。 动态库是在可执行程序运行时进行了动态链接 (所需要某个实现方法就去内存中查找). 所

    2024年02月05日
    浏览(30)
  • Linux文件(系统)IO(含动静态库的链接操作)

    fopen打开文件,fclose关闭文件 fwrite操作(写文件) fwrite函数从 ptr 里将 nitems 个大小为 size 字节的数据写进定 stream 里 hello_w.c 文件 这里我们将会在此路径得到一个写有 5 行 hello fopen 的 myfile.txt 文件,如下gif: fread操作(写文件) fread 不会在字符串末尾添加 null 终止符( \\0

    2024年04月14日
    浏览(46)
  • Linux(Ubuntu)系统临时IP以及静态IP配置(关闭、启动网卡等操作)

    前提是Linux下的网络桥接不能用,不能通过识别网卡来添加IP地址,只能通过静态写死的方式去设置IP 对于CentOS版本下的静态IP的配置可以参考这篇 Linux系统静态IP配置(CentOS) Linux终端输入: sudo ifconfig 192.168.XXX.XXX 或者 su root 进入root用户下( su ubuntu ,ubuntu是用户名再退回来

    2024年02月13日
    浏览(44)
  • 基于Linux操作系统中的MySQL数据库操作(三十)

    MySQL数据库安装 目录 一、概述 (一)什么是数据库 (二)数据库能干什么     1、企业应用     2、金融行业     3、电子商务     4、社交媒体     5、物联网 (三)为什么要用数据库,优势、特性?     1、可靠性和稳定性     2、数据管理能力     3、数据共享和集成  

    2024年02月15日
    浏览(57)
  • 【Linux操作系统】深入理解系统调用中的read和write函数

    在操作系统中,系统调用是用户程序与操作系统之间进行交互的重要方式。其中,read和write函数是常用的系统调用函数,用于在用户程序和操作系统之间进行数据的读取和写入。本文将深入介绍read和write函数的工作原理、用法以及示例代码,以帮助读者更好地理解和应用这两

    2024年02月13日
    浏览(42)
  • 动态库与静态库

    动态库(Dynamic Library)和静态库(Static Library)是软件开发中常用的两种库文件形式。 动态库:是一组共享的目标代码文件,它们在运行时动态链接到应用程序中。动态库在系统中独立存在,可以被多个应用程序共享。当应用程序运行时,操作系统会加载动态库,并在需要时

    2024年02月08日
    浏览(38)
  • 【Linux操作系统】Linux中的进程和线程的概念、区别和实现的细节

    在Linux中,进程和线程是操作系统中两个重要的执行单位。它们是对程序运行时的抽象概念,用于管理和调度计算机资源。 进程是正在运行的程序的实例。它是操作系统分配资源和调度执行的基本单位。每个进程都有自己独立的内存空间,包含代码、数据、堆栈等。进程还包

    2024年02月14日
    浏览(52)
  • 【操作系统】一篇文章带你理清Linux中的权限!

    🎬 乀艨ic: 个人主页 ⛺️说是高产但是还是过了快半个月才更新() ⭐️来看看这次的博客吧~ 上次注意到发Linux相关的点击量比其他的多很多,那就最近多更几篇Linux相关的吧() 注:Linux的不同发行版本的指令可能有所不同,本次是按照CentOS7的标准来进行追述的。 在谈

    2024年04月11日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包