文章目录
一. 用gcc生成静态库和动态库源程序准备
1.1 概念
我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入,因此在程序运行时还需要动态库的存在。
1.2 编辑生成例子程序
在终端执行以下命令,创建一个目录文件
mkdir test1
cd test1
使用vim编辑器,编写3个c语言文件
注:若没有安装 vim编辑器,可以输入命令:sudo apt install vim 进行安装。
运行命令vi hello.h
代码如下:
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif//HELLO_H
注意:进入vim,开始编辑需要点击键盘“i”,编辑完成后,按键盘“Esc”,再输入“:wq”,表示退出并保存。
运行命令vi hello.c
代码如下:
#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n", name);
}
运行命令vi main.c
代码如下:
#include "hello.h"
int main()
{
hello("everyone"); return 0;
}
1.3 将 hello.c 编译成.o 文件
输入命令使得.c文件变为.o文件,无论静态库,还是动态库,都是由.o 文件创建的。具体命令如下:
gcc -c hello.c
运行 ls 命令看是否生存了 hello.o 文件
ls
得到如下结果:
二. 静态库创建及使用
2.1创建静态库
静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a,创建静态库用 ar 命令,具体命令如下:
ar -crv libmyhello.a hello.o
运行 ls 命令看看是否生存了libmyhello.a 文件
ls
2.2 使用静态库
静态库制作完了,使用它内部的函数,只需要在使用到这些公用函数的源程序中 含这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中将公用函数连接到目标文件中。
(注意:gcc 会在静态库名前加上前缀 lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件。)
在程序 3:main.c 中,我们包含了静态库的头文件 hello.h,然后在主程序 main中直接调用公用函数 hello。下面先生成目标程序 hello,运行 hello 程序。
方法一:
命令如下:
gcc -o hello main.c -L. –lmyhello
运行程序,输入以下命令:
./hello
结果如下:
方法二:
命令如下:
gcc main.c libmyhello.a -o hello
运行./hello
,结果如下:
方法三
先生成main.o,命令如下:
gcc -c main.c
在生成可执行文件,命令如下:
gcc -o hello main.o libmyhello.a
运行./hello
,结果如下:
说明:即使删掉 libmyhello.a 静态库文件,hello可执行文件照常运行,说明静态库中的公用函数已经链接到 .o 目标文件中了。
运行命令rm libmyhello.a
删除libmyhello.a静态库文件,同样运行命令./hello
查看结果
三. 动态库创建及使用
3.1 动态库创建
动态库文件命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但其文件拓展名为.so。
命令如下:
gcc -shared -fPIC -o libmyhello.so hello.o
同样我们使用ls命令查看
3.2 使用动态库
在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的声明原型,然后用gcc命令生成目标文件时指明动态库名进行编译。
gcc -o hello main.c -L. -lmyhello
或者
gcc main.c libmyhello.so -o hello
运行./hello
发现有错误
程序报错为找不到动态库文件libmyhello.so。程序运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上诉错误而终止程序运行。我们将文件libmyhello.so复制到目录/usr/lib中就可以了。
复制命令:mv libmyhello.so /usr/lib
当我们将上述命令输入之后,发现并不能直接复制,那我们就需要切换到root用户模式再执行操作。
注意:若第一次使用 root 用户,要先激活,使用命令:sudo passwd root
然后连续输入两个密码即可
然后再输入su,接着输入密码就进入root用户模式了,再在此模式下复制动态库文件,最后输入exit退出该模式就结束了。
然后我们再次执行./hello
,运行成功
当静态库和动态库同名时,gcc优先使用动态库
四、库具体使用实例
4.1 源码
创建一个文件夹Test2
mkdir Test2
cd Test2
代码如下
x2x.c
x2y.c
test.h
main.c
结果如下:
4.2 静态库使用
将.c文件编译成.o文件
生成静态库.a文件
链接静态库文件并执行
结果正确!!
接下来使用size test命令查看test文件大小
使用ll命令可以查看文件夹所有文件的大小
4.3 动态库使用
删除静态库文件和可执行文件,只保留目标文件(方便比较大小)
生成.so文件
-fpic(小模式,代码少)必须添加
使用.so库文件,创建可执行程序
发现有错误,这是由于linux自身系统设定的相应设置的原因,即其只在/lib and/usr/lib下搜索对应的.so文件,故需将对应so文件拷贝到对应的路径(在文章开始创建动态库时也讲到过)
修改后,结果正确!!
查看文件大小
4.4 总结
通过比较我们发现静态库和动态库生成的test可执行文件是差不多大的。
五、总结
通过这次实验,了解到了Linux系统下静态库文件和动态库文件如何生成,以及静态库.a.与.so文件该如何使用