目录
一、学习并仿做示例程序
(一)编写c程序
•编写main.c文件
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
•编写hello.c文件
#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n", name);
}
•编写hello.h文件
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif
(二)生成静态库
1.将hello.c文件编译成.o文件
无论是静态库还是动态库都是由.o文件创建,所以我们需要先使用gcc将hello.c编译成.o文件:
gcc -c hello.c
2.用生成的.o文件创建静态库
静态库的命名规范是使用lib为前缀,后面跟静态库名称,扩展名为.a。所以将本次的静态库名称命名为libhello.a,并使用ar命令创建我们的libhello.a静态库文件:
ar -crv libhello.a hello.o
3.在程序中使用静态库
如何使用静态库内部函数?只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明,在gcc生成目标文件时指明对应的静态库,gcc 将会从 静态库中将公用函数连接到目标文件中。
•方法一:将 -L. 放在main.c和-lhello之间
gcc -o hello main.c -L. -lhello
注:L. 表示要连接的库在当前目录中。
(多个库:在编译命令行中,将使用的静态库文件放在 源文件后面就可以了。比如: gcc -L/usr/lib myprop.c libtest.a libX11.a libpthread.a -o myprop 其中-L/usr/lib 指定库文件的查找路径。编译器默认在当前目录下先查找指定的库文件)
•方法二:
gcc main.c libhello.a -o hello
•方法三:先生成main.o文件,再生成可执行文件
gcc -c main.c
gcc -o hello main.o libhello.a
(三)生成动态库
1.用生成的.o文件创建动态库
动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其 文件扩展名为.so,例如我们要创建的动态库名为hello,则动态库文件名为libhello.so。
使用gcc命令创建动态库文件:
gcc -shared -fPIC -o libhello.so hello.o
-shared :该选项指定生成动态连接库(让连接器生成 T 类型的导出符号表,有时候也生成 弱连接 W 类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件。
-fPIC :表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载 入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
2.在程序中使用动态库
程序中使用动态库和使用静态库完全一样,但是需要注意的是程序运行时调用动态库是在/usr/lib目录下寻找的,所以我们需要将动态库文件复制到目录/usr/lib下:
在管理员权限下用mv命令将libhello.so复制到/usr/lib目录下:
sudo mv libhello.so /usr/lib
cd到该目录下可以看到已经将libhello.so复制到/usr/lib下:
再使用gcc命令链接hello动态库重新生成hello1可执行文件:
gcc -o hello1 main.c -L. -lhello
二、应用实例
具体要求:创建一个x2x函数,x2y函数以及main函数,将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。
(一)编写c程序
•编写main.c文件
#include <stdio.h>
#include "x2x.h"
#include "x2y.h"
void main()
{
int x,y;
printf("Please input the value of x:");
scanf("%d",&x);
printf("Please input the value of y:");
scanf("%d",&y);
printf("x*x=%d\n",x2x(x));
printf("x*y=%d\n",x2y(x,y));
}
•编写x2x.c文件
#include <stdio.h>
int x2x(int x)
{
return x*x;
}
•编写x2y.c文件
#include <stdio.h>
int x2y(int x,int y)
{
return x*y;
}
•编写x2x.h文件
#ifndef X2X_H
#define X2X_H
int x2x(int x);
#endif
•编写x2y.h文件
#ifndef X2Y_H
#define X2Y_H
int x2y(int x,int y);
#endif
(二)生成静态库
用gcc分别编译为3个.o 目标文件:
gcc -c main.c x2x.c x2y.c
相关.o文件生成成功,接下来使用ar命令生成静态库:
ar -crv libsub.a x2x.o x2y.o
连接静态库生成可执行文件:
gcc -o sub1 main.c -L. -lsub
使用命令ls查看可执行文件大小:
ls -lh sub1
可以看到该文件大小为17K。
(三)生成动态库
利用上面生成的.o文件创建一个动态库:
gcc -shared -fPIC -o libsub.so x2x.o x2y.o
利用动态库创建可执行文件:
gcc main.c libsub.so -o sub2
使用命令ls查看静态库、动态库以及他们的可执行文件大小:
可以看到静态库生成可执行文件为16912B而动态库生成的可执行文件为16856B;动态库.so文件大小为15696B,静态库.a文件大小为2592B。
三、结论
结论:
通过比较发现静态库要比动态库要小很多,但生成的可执行文件大小只存在极小的差别。