Linux静态库与动态库的创建与使用

1. 在Linux中创建静态库与动态库

1.1 创建静态库与动态库前的准备工作

首先创建一个目录file1,用来保存文件

在这里插入图片描述

用nano等文本编辑器编辑生成所需要的三个文件

程序1:hello.h

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

程序2:hello.c

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

程序3:main.c

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

将hello.c编译成.o文件

gcc -c hello.c

在这里插入图片描述

1.2 由.o文件创建静态库

创建静态库用ar命令,静态库的命名规范是以"lib"为前缀,".a"为扩展名,我们将静态库命名为"super",可以在系统提示符下输入以下命令创建静态库

ar -crv libsuper.a hello.o

在这里插入图片描述

在程序中使用静态库

先输入以下代码生成可执行文件"hello"

gcc main.c libsuper.a -o hello

然后用**./hello**来运行程序

在这里插入图片描述

1.3 由.o文件创建动态库

和静态库的命名规范类似,其前缀为"lib",但其文件扩展名为".so",我们将动态库也命名为"super",可以在系统提示符下输入以下命令创建动态库

gcc -shared -fPIC -o libsuper.so hello.o

在程序中使用动态库

先输入以下代码生成可执行文件hello1

gcc main.c libsuper.so -o hello1

在这里插入图片描述

同样使用./hello1来运行程序,但此时我们遇到了如下问题

在这里插入图片描述

这是因为虽然连接时用的是当前目录的动态库,但是运行时,是到/usr/lib中找文件的,将文件libsuper.so复制到目录/usr/lib就能解决。

具体使用如下代码:

sudo mv libsuper.so /usr/lib

在这里插入图片描述

2. 静态库与动态库的应用

2.1 实例1

同样创建一个目录用来保存文件

mkdir file2
cd file2

接下来用nano等文本编辑器来编写我们所需要的四个文件A1.c、A2.c、A.h、test.c

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);
}

在这里插入图片描述

生成可执行文件A1.o与A2.o

gcc -c A1.c A2.c

在这里插入图片描述

生成静态库文件

ar crv libsup.a A1.o A2.o

在这里插入图片描述

在这里插入图片描述

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

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

在这里插入图片描述

共享库文件.so文件的生成与使用

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

gcc -c -fpic A1.c A2.c

生成共享库.so文件

gcc -shared *.o -o libsofile.so

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

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

此时却出现如下错误

在这里插入图片描述

运行ldd test,查看连接情况

在这里插入图片描述

发现找不到对应的.so文件

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

sudo cp libsofile.so /usr/lib

再次执行./test,即可成功运行

在这里插入图片描述

同时可以直接使用以下代码来使用相应库文件

gcc -o test test.c -L. -lsofile

在这里插入图片描述

其中:"-L.“表示在前目录下,可自行定义路径path,及使用”-Lpath"即可;"-lsofile"中"-l"后接对应库文件的名字(除开lib),我们使用的是libsofile.so,所以为"-lsofile"。

2.2 实例2

同样使用上述方法创建一个文件夹"ep"用来保存所需的文件

并在ep文件夹下编写程序sub1.c、sub2.c、main.c

程序1:sub1.c

float x2x(int a,int b)
{
return (float)(a*b);
}

程序2:sub2.c

float x2y(int a,int b)

{
return (float)(a/b);
}

程序3:main.c

#include<stdio.h>
#include"sub1.c"
#include"sub2.c"
void main()
{
int x=5,y=4;
float s;
s=x2x(x,y)+x2y(y,x);
printf("%f\n",s);
}

用gcc分别编译成三个.o文件

在这里插入图片描述

使用ar工具将sub1.o、sub2.o生成一个静态库文件

ar crv libexp.a sub1.o sub2.o

在这里插入图片描述

用gcc与静态库进行连接,生成可执行文件

gcc -o sq main.c libexp.a
./sq

在这里插入图片描述

同样使用实列1的方法将sub1.o、sub2.o生成一个.so动态库文件,然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序

gcc -c -fpic sub1.c sub2.c
gcc -shared *.o -o libsoexp.so
gcc -o sr main.c libsoexp.so
./sr

在这里插入图片描述

在创建动态库的时候我们会遇到错误

在这里插入图片描述

经过多番排查,发现是文件重复定义的问题,需要使用rm命令将多余的main.o删除,这里就不再详细叙述。

3. 总结

在程序中使用动态库时,我们需要将动态库文件复制到目录/usr/lib中,否则会因为错误而终止程序运行。这是因为程序在运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。

这也进一步说明动态库在程序运行时是需要的。当未指定静态库还是动态库时,且动态库和动态库同名并同时存在,优先使用动态库。

4. 参考文献

https://blog.csdn.net/qq_43279579/article/details/109026927

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值