文章目录
一、用gcc生成静态库和动态库
1.准备
(1)创建目录并编写函数
hello.h
hello.c
main.c
(2)将hello.c 编译成.o文件
输入gcc -c hello.c 再运行ls命令可看到生成了hello.o文件
2.静态库的使用
(1)由.o文件创建静态库
输入ar -crv libmyhello.a hello.o可看到生成了libmyhello.a文件
(2)在程序中使用静态库
方法一:gcc -o hello main.c -L. -lmyhello
方法二:gcc main.c libmyhello.a -o hello
方法三:先输入gcc -c main.c 生成main.o,再输入gcc -o hello main.c libmyhello.a生成可执行文件
(3)静态库特点验证
在程序编译时其会被连接到目标代码中,程序运行是则不需要静态库的存在。在删掉静态库的情况下,运行可执行文件,发现程序仍旧正常运行,表明静态库跟程序执行没有联系。同时,也表明静态库是在程序编译的时候被连接到代码中的。
3.动态库的使用
(1) 创建动态库
gcc -shared -fPIC -o libmyhello.so hello.o
shared:表示指定生成动态链接库,不可省略
-fPIC:表示编译为位置独立的代码,不可省略
可以看到动态库文件生成
(2)在程序中使用动态库
gcc -o hello main.c -L. -lmyhello
再运行可执行文件hello,会出现错误
错误是因为程序在运行时,会在/usr/lib的目录查找需要的动态文件,所以需把libmyhello.so复制到目录下
4.静态库和动态库对比
先删除除.c和.h外的所有文件
再创建静态库文件和动态库文件
发现静态库和动态库同时存在时,优先使用动态库,这里同上把libmyhello.so复制到目录下即可成功运行
二、库的使用实战
在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。
1.准备
创建如下文件
main.c
#include"sub1.h"
#include"sub2.h"
#include<stdio.h>
int main()
{
int a,b;
printf("please input a");//输入a的值
scanf("%d",&a);
printf("please input b");//输入b的值
scanf("%d",&b);
printf("%d/%d=%.2f\n",b,a,x2x(a,b));
printf("%d*%d=%d\n",a,b,x2y(a,b));
return 0;
}
sub1.h
#ifndef __SUB1_H
#define __SUB1_H
float x2x(int a,int b); //计算b除以a
#endif
sub1.c
#include "sub1.h"
float x2x(int a,int b)
{
float ans;
ans=(float)b/a;
return ans;
}
sub2.h
#ifndef __SUB2_H
#define __SUB2_H
int x2y(int a,int b); //计算a*b
#endif
sub2.c
#include "sub2.h"
int x2y(int a,int b)
{
return a*b;
}
2.静态库的生成与使用
(1)将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件,将x2x、x2y目标文件用 ar工具生成 .a 静态库文件
·编译.o目标文件
输入命令gcc -c main.c sub1.c sub2.c编译得到main.o、sub1.o、sub2.o三个目标文件
·编译libxx.a静态库文件
输入命令ar -crv libsub1.a sub1.o 和ar -crv libsub2.a sub2.o编译生成libsub1.a和libsub2.a静态库文件
(2)用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小
·使用命令gcc main.o libx2.a -o main链接main.o和libx2.a文件生成可执行文件main
·执行可执行文件main
使用命令./main执行该可执行文件
·测试是否真的静态库链接成功
删除静态库libx2.a目标文件,再次执行该可执行文件
以上说明静态库链接生成的可执行文件运行时不需要该静态库,因为该静态库已经被编译到可执行文件中了。
·main1文件大小
可以看到使用静态库的文件大小为8.4k
3.使用动态库
(1)编译动态库文件libx2.so
·.o目标文件已经在上面编译静态库文件时生成了,因此这里直接编译动态库文件。使用命令gcc -shared -o libx2.so sub1.o sub2.o生成libx2.so
(2)链接为可执行文件
·使用命令gcc main1.o -L. -lx2 -o main2链接两个目标文件生成可执行文件main2
·执行生成的可执行文件main
使用命令./main2执行该可执行文件main2
发现报错如下:
原因:
程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。
解决方法:
将libx2.so 复制到目录/usr/lib 中,再次执行./main运行(若提示权限不够则以使用sudo mv libx2.so /usr/lib该命令)
·main2文件大小
发现动态库的文件大小为8.3k,比静态库的小
总结
通过使用静态库和动态库分别链接生成可执行文件main,我深入的了解到了不同库函数的链接的作用是不一样的。静态库链接是直接在程序编译时就将其组装到一起,可以不依赖于静态库就能运行;而动态库链接是在程序运行时才将其载入内存运行且不能够缺少,否则不能运行。