【Linux操作系统】--动态库和静态库的制作和使用

目录

动态库和静态库

动静态库的制作

静态库的制作

makefile文件

生成静态库

最后库制作代码

运用静态库

【自己写一可执行程序】:

用gcc命令编译

用makefile文件编译

动态库的制作

形成.o文件

使用动态库

两种库的混合使用


动态库和静态库

在linux中查看库,我们可以使用ldd命令,查看可执行程序,比如上面文件中我们写的mytest可执行程序

[wjy@VM-24-9-centos 30]$ ldd mytest
	linux-vdso.so.1 =>  (0x00007ffeb5562000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fe8a82e7000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fe8a86b5000)

而这个库它存在于一个目录的路径下的,这里是一个软连接,而这个2.17指向的就是一个C的库。查看这个文件可以看到,c库有2156592个文件。所谓的库是系统上真正存在的一个文件,

[wjy@VM-24-9-centos 30]$ ls /lib64/libc.so.6 -l
lrwxrwxrwx 1 root root 12 Nov 23 17:52 /lib64/libc.so.6 -> libc-2.17.so
[wjy@VM-24-9-centos 30]$ ls /lib64/libc-2.17.so -l
-rwxr-xr-x 1 root root 2156592 Oct 14  2021 /lib64/libc-2.17.so

Linux中,一般库分两种库,动态库和静态库

  • 如果是动态库,库文件是以.so作为后缀的。
  • 如果是静态库,库文件是以.a作为后缀的。

ps1:动静态库它们就是文件,它们就是在磁盘上的一个文件。

ps2:库的真实名字:去掉lib前缀,去掉.a/.so之后包含的后缀,剩下的就是库的名字。

需要注意的一点是,在编写C++程序的时候,C++的程序名只能由三种后缀:.cpp/.cc/.cxx这三种,如果是其他的后缀如.cyy编译就会报错

[wjy@VM-24-9-centos 30]$ touch test.cc
[wjy@VM-24-9-centos 30]$ vim test.cc
[wjy@VM-24-9-centos 30]$ cat test.cc
#include <iostream>

int main()
{
  std::cout<<"hello world!"<<std::endl;
  return 0;
}
[wjy@VM-24-9-centos 30]$ g++ test.cc
[wjy@VM-24-9-centos 30]$ ./a.out
hello world!
[wjy@VM-24-9-centos 30]$ mv test.cc test.cpp
[wjy@VM-24-9-centos 30]$ g++ test.cpp
[wjy@VM-24-9-centos 30]$ ./a.out
hello world!
[wjy@VM-24-9-centos 30]$ mv test.cpp test.cxx
[wjy@VM-24-9-centos 30]$ g++ test.cxx
[wjy@VM-24-9-centos 30]$ ./a.out
hello world!

[wjy@VM-24-9-centos 30]$ mv test.cxx test.cyy
[wjy@VM-24-9-centos 30]$ g++ test.cyy
test.cyy: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
[wjy@VM-24-9-centos 30]$ 

当我们使用静编译,编写makefile文件的时候,在后面要加-static选项。

 默认gcc动态链接编译:在上面我们写过一个test.c代码是c语言的,并且它的编译方式是gcc -o $@ $^,通过file操作可以发现,它是动态编译的。

gcc静态链接编译:如果编译静态链接,用file查看它是静态的链接。如果静态编译出现这样的错误:/usr/bin/ld: cannot find -lc,那么输入这个命令:sudo yum install glibc-static,就可以搞定啦。我们同时也发现,静态链接的体积非常大。

那为什么有时候会报错呢?因为一般服务器,可能美欧内置语言的静态库,而只有动态库。

 动态库和静态库的区别

实际上我们在代码中运用库函数,如C中的printf,我们需要通过链接库的方式,那么链接库的方式有两种,一种是静态的,一种是动态的。

静态库一般就是把库中的内容拷贝进可执行程序,这样如果拷贝到执行程序,执行城区之后的代码将不再依赖库,同时也造成了可执行程序非常大。

而动态库,只是把要关联的函数关联起来,不会进行拷贝的行为,当需要执行库函数代码,我们直接跳转到库当中就可以执行了。那么动态库是怎么实现每个程序都可以用呢,就是通过地址空间和动态库的映射,实现共享,所以我们通过file查看的动态库可以看到上面写着share共享。所以动态库它生成的体积小,但是可移植性是存在问题的,如果库缺失了,那么对应的函数就找不到了。而静态库最然体积大,但是不依赖第三方库,哪怕删掉也没有关系。

动静态库的制作

库本身就是二进制的文件,我们如何得知一个库给我们提供了什么方法呢?

一套完整的库包含两个东西(其实还有一个说明文档,但这里我们不关心)

  • 1.库文件本身
  • 2.头文件.h  :会说明库中暴露出来的方法的基本使用。它被安装在/usr/include目录下。其中就有我们最熟悉的stdio.h,查看stdio.h文档里面是文本文档,并不是二进制。

我们在C/C++中,为什么写代码,有时候把声明放在.h中,把实现放入.c/.cpp中呢?为什么这么设计?

因为我们要制作库,库的好处除了方便使用,还有最重要的一点是私密。

静态库的制作

先在当前目录下新建一个目录test_lib保存我们自己写的库文件。其中我们写两个.c文件和两个.h文件

[wjy@VM-24-9-centos test_lib]$ ll
total 16
-rw-rw-r-- 1 wjy wjy 60 May  1 15:49 add.c
-rw-rw-r-- 1 wjy wjy 66 May  1 15:49 add.h
-rw-rw-r-- 1 wjy wjy 61 May  1 16:42 sub.c
-rw-rw-r-- 1 wjy wjy 66 May  1 16:42 sub.h

[wjy@VM-24-9-centos test_lib]$ cat add.h
#pragma once 
#include <stdio.h>

extern int my_add(int x,int y);
[wjy@VM-24-9-centos test_lib]$ cat add.c
#include "add.h"

int my_add(i
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,我可以回答你的问题。 首先,我需要确认一下你的操作系统是什么,因为制作静态库动态库的步骤会有所不同。 如果你使用的是类Unix操作系统(如Linux、macOS等),可以按照以下步骤制作可伸缩循环队列的静态库动态库: 1. 编写可伸缩循环队列的源代码,并保存为一个或多个源文件(例如,queue.c)。 2. 在命令行中使用gcc编译源文件,生成目标文件(例如,queue.o): ``` gcc -c queue.c -o queue.o ``` 3. 使用ar命令将目标文件打包成静态库(例如,libqueue.a): ``` ar rcs libqueue.a queue.o ``` 这会生成一个静态库文件libqueue.a,其中包含可伸缩循环队列的函数实现。 4. 使用gcc编译源文件并链接静态库,生成可执行文件(例如,main): ``` gcc main.c -o main -L. -lqueue ``` 这会生成一个可执行文件main,其中包含了对可伸缩循环队列静态库链接。 5. 使用gcc编译源文件,生成动态库(例如,libqueue.so): ``` gcc -shared -o libqueue.so queue.o ``` 这会生成一个动态库文件libqueue.so,其中包含可伸缩循环队列的函数实现。 6. 使用gcc编译源文件并链接动态库,生成可执行文件(例如,main): ``` gcc main.c -o main -L. -lqueue ``` 这会生成一个可执行文件main,其中包含了对可伸缩循环队列动态库链接。 以上就是制作可伸缩循环队列的静态库动态库的步骤,希望能帮助到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值