文章目录
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