【Linux】静态库和共享库一分钟快速上手

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

前言

程序库,对于程序原来说是非常重要的。但不少人对其不太了解,接下来一起学习其中的奥秘吧!
简单来说,程序库可以分为静态库和共享库。它们包含了数据和执行代码的文件。其不能单独执行,可以作为其他执行程序的一部分来完成某些功能。库的存在,可以使得程序模块化,可以加快程序的再编译,可以实现代码的重用,可以使得程序便于升级

对比

静态库是指在程序运行前就已经加入到执行代码中,成为执行程序的一部分。程序会把静态库加载到自己的内存当中,比如在Linux环境下,编译产生多个a.out,那么相当于每个a.out里面都会存有静态库的内存,从而大大削减了程序的运行时间,但是增加了空间大小,另外静态库更新比较麻烦,一般不做推荐

所以静态库适用于对空间要求比较低,对时间要求比较高的核心程序中

而相比共享库(动态库),是在执行程序启动时加载到执行程序中。它是这几个a.out用到库的时候一起去调用库文件,被多个执行程序共享使用。因此时间上效率就会下降,虽然节省了空间,但是耗费了时间。另外动态库是独立的,便于维护更新

所以动态库一般用在对时间要求低的,对空间要求高的设备上。

创建静态库

首先创建几个.cpp文件
创建两个cpp文件

[bsk@localhost linux_system]$ touch sum.cpp
[bsk@localhost linux_system]$ ls
sum.cpp
[bsk@localhost linux_system]$ vi sum.cpp 
[bsk@localhost linux_system]$ ls
sum.cpp
bsk@localhost linux_system]$ touch div1.cpp
[bsk@localhost linux_system]$ cd d
bash: cd: d: No such file or directory
[bsk@localhost linux_system]$ vi div1.cpp 

两个文件内容如下:

  2 int sum(int a, int b)                                                                                                                                                                                          
  3 {
  4 return a+b;
  5 }

  2 int div1(int a, int b)                                                                                                                                                                                          
  3 {
  4 return a/b;
  5 }

然后将.cpp文件生成 .o文件

[bsk@localhost linux_system]$ g++ -c sum.cpp -o sum.o
[bsk@localhost linux_system]$ ls
div1.cpp  sum.cpp  sum.o
[bsk@localhost linux_system]$ g++ -c div1.cpp -o div.o

再使用ar工具制作静态库

[bsk@localhost linux_system]$ ar rcs libmymath.a sum.o div.o
[bsk@localhost linux_system]$ ls
div1.cpp  div.o  libmymath.a  sum.cpp  sum.o

再编写主函数test.cpp

  1 #include<iostream>
  2 using namespace std;
  3 int div1(int a,int b);
  4 int sum(int a, int b); 
                                                                                                                                                                                          
  5 int main()
  6 {
  7 int a = 10;
  8 int b = 2;
  9 cout<<"a+b= " <<sum(a,b)<<endl;
 10 cout<<"a/b= " <<div1(a,b)<<endl;
 11 return 0;
 12 }
     

编译静态库到可执行文件中

[bsk@localhost linux_system]$ g++  libmymath.a test.cpp  -o a.out

即可运行a.out

[bsk@localhost linux_system]$ ls
a.out  div1.cpp  div.o  libmymath.a  sum.cpp  sum.o  test.cpp
[bsk@localhost linux_system]$ ./a.out 
a+b= 12
a/b= 5

其实上面这种方法有一点漏洞,就是头文件没有单独写出来

` #ifndef _MYMATH_H_                                                                 
  2 #define _MAMATH_H_
  3 int div1(int a,int b);
  4 int sum(int a, int b);
  5  
  6 #endif
~                 `

把头文件单独写出来,再在test.cpp中引用头文件即可。

可以再创建 lib 和inc 两个目录,然后把他们分别放进去

[bsk@localhost linux_system]$ mkdir inc
[bsk@localhost linux_system]$ mkdir lib
[bsk@localhost linux_system]$ mv *.h inc/
[bsk@localhost linux_system]$ mv *.a lib

即可运行

[bsk@localhost linux_system]$ g++ test.cpp  ./lib/libmymath.a  -o a.outy -I ./inc/
[bsk@localhost linux_system]$ ls
a.out  a.outy  div1.cpp  div.o  inc  lib  sum.cpp  sum.o  test.cpp  -Wall
[bsk@localhost linux_system]$ ./a.outy
a+b= 12
a/b= 5

动态库

将.cpp文件生成 .o文件(要生成与位置无关的代码 -fPIC)

[bsk@localhost sourse]$ g++ -c sum.cpp  -o sum.o -fPIC
[bsk@localhost sourse]$ g++ -c div1.cpp  -o div1.o -fPIC
[bsk@localhost sourse]$ ls
div1.cpp  div1.o  sum.cpp  sum.o
[bsk@localhost sourse]$ 

使用g++ -shared 制作动态库
g++ -shared -o lib库名.so sum.o div1.o

[bsk@localhost sourse]$ g++ -shared -o libmymath.so sum.o div1.o
[bsk@localhost sourse]$ ls
div1.cpp  div1.o  libmymath.so  sum.cpp  sum.o
[bsk@localhost sourse]$ 

编译可执行文件时,指定所使用的动态库
-l 指定库名 -L 指定库路径

[bsk@localhost dynamiclib]$ g++ test.cpp  -o a.out -l mymath -L ./lib -I./inc
[bsk@localhost dynamiclib]$ ls
a.out  inc  lib  sourse  test.cpp
[bsk@localhost dynamiclib]$ ./a.out 
./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
[bsk@localhost dynamiclib]$ 

如上所示竟然出错了,为什么呢?
首先先来了解一下链接器和动态链接器,
链接器: 工作于链接阶段,工作时需要 -l 和 -L
动态链接器:工作于程序运行阶段,工作时需要提供动态库所在目录位置。
所以这个错误就是动态链接库因为找不到库文件,从而报错。
那我们应该如何去解决呢?

  1. 方法一:通过环境变量(临时生效)

方法也很简单,就是修改一下环境变量·
即LD_LIBRARY_PATH = 动态库路径。

[bsk@localhost dynamiclib]$ export LD_LIBRARY_PATH=./lib
[bsk@localhost dynamiclib]$ ./a.out 
a+b= 12
a/b= 5

export的意思是让环境变量设定的值生效。

但是当我们关闭终端后,再重新打开一个终端(新进程),再运行的话,就会又报错,因为·我们设置的环境变量只能在当前进程中生效,所以要想它永久生效的话,就要修改配置文件了。

  1. 方法二:永久生效,写入终端配置文件(建议使用绝对路径)
[bsk@localhost ~]$ vi ~/.bashrc //修改配置文件
//进入后写入 export LD_LIBRARY_PATH=./lib
[bsk@localhost ~]$ . .bashrc 
//重新·运行一下

即可永久生效


[bsk@localhost dynamiclib]$ ./a.out 
a+b= 12
a/b= 5

但是还有一点缺点,就是当我们的/lib是相对命令,如果我们的文件相对于这个lib的路径发生改变了,所以就会又报错。所以一般我们就要使用绝对路径。
摒弃以上做法:

  1. 方法三:拷贝法(不推荐)

我们还可以把libmymath.os文件(自定义动态库)拷贝到系统根目录lib下(标准c库所在目录位置)
即可生效
但是此种方法也有一个缺点,就是它修改的系统级的目录,在系统中添加了自己的文件,不可靠,所以也不推荐使用

  1. 方法四:配置文件法

其实,我们还可以通过修改配置文件法:
首先: sudo vi /etc/ld.so.conf
然后写入 动态库的绝对路径,保存退出。
再重新运行,使配置文件生效
sudo ldconfig -v
此后再./a.out就可以永久成功啦文章来源地址https://www.toymoban.com/news/detail-713950.html

libmymath.so
[bsk@localhost lib]$ pwd
/home/bsk/test1/linux_system/dynamiclib/lib
[bsk@localhost lib]$ vi /etc/ld.so.conf

[bsk@localhost lib]$ sudo vi /etc/ld.so.conf
[sudo] password for bsk: 
[bsk@localhost lib]$ sudo ldconfig -v
.......

[bsk@localhost dynamiclib]$ ./a.out 
a+b= 12
a/b= 5


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

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

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

相关文章

  • Linux下动态库和静态库编译实践

    之前写过JNI的文章,在JNI实践过程中,也涉及到对动态库/静态库的一些编译实践,这里统一记录一下。 注意 :-fPIC编译选项可使GCC生成位置无关代码,简单来说生成的代码中的函数与全局变量均为相对地址,通过GOT (Global offset table)来确定其位置,这种方式引入了一层额外的

    2024年01月17日
    浏览(41)
  • vue3探索——5分钟快速上手大菠萝pinia

    温馨提示:本文以vue3+vite+ts举例,vite配置和ts语法侧重较少,比较适合有vuex或者vue基础的小伙伴们儿查阅。 yarn npm pnpm 在 src/main.ts 中引入pinia(根存储),并传递给应用程序。 在根目录下新建文件夹,这里我命名为 store ,再在文件夹下新建一个 index.ts 文件( src/store/index.ts

    2024年02月09日
    浏览(39)
  • linux下g++链接动态库和静态库

    头文件的作用: include的作用就是复制内容到当前文件 井号开头的就是预处理指令,由预处理器处理,预处理阶段不关心代码,只处理预处理指令。 头文件主要 一是为了解决代码都写在一个文件太大了,二是把变量,结构体,函数声明这些固定的放在一起 函数只要声明了,

    2024年02月09日
    浏览(49)
  • Linux中静态库和动态库的使用

    介绍: 库是一个二进制文件,包含的代码可被程序调用 标准C库、数学库、线程库… 库有源码,可下载后编译;也可以直接安装二进制包 位置一般放在:/lib /usr/lib 库的知识 库是事先编译好的,可以复用的代码 在os上运行的程序基本上都要使用库,使用库可以提高开发效率

    2024年01月25日
    浏览(36)
  • 如何在linux下制作静态库和动态库

    静态库顾名思义是静态的,即程序编译链接时,会把静态库的代码链接到可执行文件中。运行时不需要静态库(将静态库删了也能运行)。 相当于静态库的代码复制到了可执行文件中。 分别有如下add.c add.h sub.c sub.h四个文件格式。 首先把.c文件都编译成.o文件。使用下面命令

    2024年01月24日
    浏览(46)
  • 【开源串口屏方案】五步教你设计串口屏,5分钟快速上手

    目录 前言 一、什么是串口屏? 二、串口屏原理与组成 三、硬件制作 四、实现方法 1.硬件设备 2.环境依赖 3.界面设计 4.编写串口通信代码和示例  本文详细介绍串口屏原理、设计方法、实现步骤,给出完整代码实例,30分钟即可完成串口屏的设计使用。适合初学者快速上手。

    2024年02月05日
    浏览(39)
  • linux并发服务器 —— 动态库和静态库实战(一)

    -E 预处理指定源文件 -S 编译指定源文件 -c 汇编指定源文件 -o 生成可执行文件 -I directory 指定Include包含文件的搜索目录 -g 编译的时候生成调试信息 -D 在程序编译时指定一个宏 -w 不生成任何的警告信息 -Wall 生成所有警告 -On n:0~3;表示编译器的优化选项级别 O0 - 不优化;O1 -

    2024年02月11日
    浏览(50)
  • 10分钟快速上手LLM大模型Python前端开发(三)之显示模块(一)

    微信公众号:leetcode_algos_life,代码随想随记 小红书:412408155 CSDN:https://blog.csdn.net/woai8339?type=blog GitHub: https://github.com/riverind 抖音【暂未开始,计划开始】:tian72530 知乎【暂未开始,计划开始】:happy001 本系列主要应用于大模型前端展示,十分钟快速上手前端系列。 该文章

    2024年01月16日
    浏览(42)
  • Linux操作命令&静态库和动态库区别&大小端&孤儿僵尸进程

    cd:切换当前目录 ls:查看当前文件与目录 grep:通常与管道符命令一起使用,用于对一些命令的输出进行筛选和加工 cp:复制文件或文件夹 mv:移动文件或文件夹 rm:删除文件或文件夹 ps:查看进程情况 kill:向进程发送信号 tar:对文件进行打包 cat:查看文件内容 top:查看

    2024年02月16日
    浏览(41)
  • C++单元测试GoogleTest和GoogleMock十分钟快速上手(gtest&gmock)

    下载 安装 重要文件 googletest gtest/gtest.h libgtest.a libgtest_main.a 当不想写 main 函数的时候,可以直接引入 libgtest_main.a; 否则 googlemock gmock/gmock.h libgmock.a libgmock_main.a 一 .断言 gtest 中的断言分成两大类: ASSERT_* 系列:如果检测失败就直接退出 当前函数 EXPECT_* 系列:如果检测失败

    2024年02月06日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包