IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 在Linux系统(Ubuntu)下静态库与动态库文件的生成与使用 -> 正文阅读

[系统运维]在Linux系统(Ubuntu)下静态库与动态库文件的生成与使用

?

目录

一、Linux系统中函数库的类型

二、hello实例使用库

(一)、准备步骤

(二)、静态库使用

(三)、动态库使用

(四)、静态库与动态库比较

三、静态库实例

(一)、构建新文件夹,编写程序

(二)、静态库.a 文件的生成与使用

(三)、共享库.so 文件的生成与使用

四、动态库实例

(一)、程序编写?

(二)、用gcc分别编译为3个.o 目标文件?

(三)、将目标文件生成静态.a文件

(四)、观察文件大小

(五)、将目标文件生成动态库.so文件并与main函数链接

(六)、记录大小并与静态库对比

五、实验总结

六、参考文献


一、Linux系统中函数库的类型

函数库分为静态库和动态库。

  • 静态库
    在程序编译时会被连接到目标代码中,程序运行是则不需要静态库的存在。
  • 动态库
    在程序编译时不会被连接到目标代码中,而是程序运行时载入的。
    两者区别:前者是编译连接的,后者是程序运行载入的。

二、hello实例使用库

(一)、准备步骤

1.创建一个作业目录test1,保存本次练习文件。

mkdir test1
cd test1

2.hello代码?,使用gedit文本编辑器生成hello.c,hello.h,main.c三个文件,三个文件源代码如下

程序一:hello.h文件

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif //HELLO_H

?程序二:hello.c?

#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n", name);
}

程序三:main.c

#include "hello.h"
int main()
{
hello("everyone");
return 0;
}

3.将 hello.c 编译成.o 文件并观察是否编译成功?

 gcc -c hello.c
 ls

?4.由.o 文件创建静态库并观察

创建静态库的工具:ar

静态库文件命名规范:以lib作为前缀,是.a文件

 ar -crv libmyhello.a hello.o
 ls

?

(二)、静态库使用

?1.含这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明静态库名,gcc 将会从 静态库中将公用函数连接到目标文件中。注意,gcc 会在静态库名前加上前缀 lib,然后追 加扩展名.a 得到的静态库文件名来查找静态库文件。

方法一:

 gcc -o hello main.c -L. –lmyhello

方法二:

gcc main.c libmyhello.a -o hello

?方法三:

先生成 main.o,再生成可执行文件

gcc -c main.c
gcc -o hello main.o libmyhello.a

本次采用的是方法三,操作结果为:??

?2.验证静态库是否生成成功

打开文件

./hello

删除静态库文件试试公用函数 hello 是否真的连接到

rm libmyhello.a

?3.通过观察发现程序照常运行,证明表明静态库跟程序执行没有联系以及静态库中的公用函数是在编译过程中直接被调用的。?

?

?(三)、动态库使用

1.创建动态库
创建动态库的工具:gcc
动态库文件命名规范:以lib作为前缀,是.so文件

gcc -shared -fPIC -o libmyhello.so hello.o
shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略

gcc -shared -fPIC -o libmyhello.so hello.o
ls

?

?2.在程序中使用动态库?

输入命令gcc main.c libmyhello.so -o hello 或?gcc -o hello main.c -L. -lmyhello

发现在显示文件时没有问题,但在./hello 会提示出错,因为虽然连接时用的是当前目录的动态库,但是运行时,是到 /usr/lib 中找库文件的,将文件 libmyhello.so 复制到目录/usr/lib 中就可以了。?

mv libmyhello.so /usr/lib

?

?发现无权限,此时我们可以用sudo命令解决

sudo mv libmyhello.so /usr/lib

?

(四)、静态库与动态库比较

1.先删除除.c 和.h 外的所有文件,恢复成我们刚刚编辑完举例程序状态

sudo rm -f hello hello.o /usr/lib/libmyhello.so
ls

2.再来创建静态库文件 libmyhello.a 和动态库文件 libmyhello.so?

gcc -c hello.c
ar -cr libmyhello.a hello.o
gcc -shared -fPIC -o libmyhello.so hello.o
ls

3.运行 gcc 命令来使用函数库 myhello 生成目 标文件 hello,并运行程序 hello

gcc -o hello main.c -L. -lmyhello

?4.结果观察

?发现在执行可执行文件,会报一个错误,可见当静态库和动态库同时存在的时候,程序会优先使用动态库。

三、静态库实例

(一)、构建新文件夹,编写程序

A1.c

#include <stdio.h>
void print1(int arg){
printf("A1 print arg:%d\n",arg);
}

A2.c

#include <stdio.h>
void print2(char *arg){
printf("A2 printf arg:%s\n", arg);
}

A.h

#ifndef A_H
#define A_H
void print1(int);
void print2(char *);
#endif

test.c

#include <stdlib.h>
#include "A.h"
int main(){
print1(1);
print2("test");
exit(0);
}

?程序构建如下:?

?

(二)、静态库.a 文件的生成与使用

1.生成目标文件

gcc -c A1.c A2.c

?2.生成静态库.a 文件

ar crv libafile.a A1.o A2.o

?3.使用.a 库文件,创建可执行程序(若采用此种方式,需保证生成的.a 文件与.c 文件保 存在同一目录下,即都在当前目录下)

gcc -o test test.c libafile.a
./test

(三)、共享库.so 文件的生成与使用

1.生成目标文件(xxx.o)(此处生成.o 文件必须添加"-fpic"(小模式,代码少),否则在生成.so 文件时会出错)

gcc -c -fpic A1.c A2.c

?2.生成共享库.so 文件

gcc -shared *.o -o libsofile.so

?3.使用.so 库文件,创建可执行程序

gcc -o test test.c libsofile.so
./test

?解决办法:这是由于 linux 自身系统设定的相应的设置的原因,即其只在/lib and /usr/lib 下搜索对应 的.so 文件,故需将对应 so 文件拷贝到对应路径。?

sudo cp libsofile.so /usr/lib

?

?同时可直接使用 gcc -o test test.c -L. -lname,来使用相应库文件 其中, -L.:表示在当前目录下,可自行定义路径 path,即使用-Lpath 即可。 -lname:name:即对应库文件的名字(除开 lib),即若使用 libafile.a,则 name 为 afile; 若要使用 libsofile.so,则 name 为 sofile)。

?

?

四、动态库实例

详细过程可参照hello程序过程

(一)、程序编写?

?程序一:lcx.c

float x2x(int a,int b)
{
	float c=0;
	c=a+b;
	return c;
}

程序二:lcy.c

float x2y(int a,int b)
{
	float c=0;
	c=a*b;
	return c;
}

?程序三:lc.h

#ifndef LC_H
#define LC_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

程序四:main.c

#include<stdio.h>
#include"lc.h"
void main()
{
	int a,b;
	printf("Please input the value of a:");
	scanf("%d",&a);
	printf("Please input the value of b:");
	scanf("%d",&b);
	printf("a+b=%.2f\n",x2x(a,b));
	printf("a*b=%.2f\n",x2y(a,b));
}

?代码运行如下:

?

(二)、用gcc分别编译为3个.o 目标文件?

gcc -c lcx.c lcy.c main.c

?

?

(三)、将目标文件生成静态.a文件

ar crv liblc.a lcx.o lcy.o
gcc -o main main.o liblc.a

注:在进行文件链接时,务必要注意需要用之前生成的.o文件,不然的话会报错?

代码运行如下:

?

?

(四)、观察文件大小

在linux下使用“ls -l”或者“ls -al”或者“ll”命令查看文件及目录详情

?

?

(五)、将目标文件生成动态库.so文件并与main函数链接

gcc -shared -fPIC -o liblc.so lcx.o lcy.o
gcc -o main main.o liblc.so

?代码运行如下:

?

(六)、记录大小并与静态库对比

动态库:

?静态库:

?对比可知,静态库占用空间更少。

?

?

五、实验总结

? ? ? ?通过本次实验,使我初次了解并熟悉了静态库和动态库的相关知识,使我能够自主的生成静态库和动态库,进一步理解二者之间的差别。同时通过本次实验,加强了我对?Linux系统的运行操作,加强了对gcc等相关编译工具的运用。
?

?

六、参考文献

gcc生成静态库.a和动态库.so_Harriet的博客-CSDN博客

Ubuntu实操二:静态库与动态库文件的生成与使用_Lc-Yusheng的博客-CSDN博客

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-09 16:39:50  更:2021-10-09 16:41:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 18:23:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码