一、gcc生成静态库.a和动态库。so动态库
1.准备工作
第 1 步:编辑生成例子程序 hello.h、hello.c 和 main.c。
(1)创建一个名为homework 1的文件夹将本次作业存放在里面。
(2) 然后用 vim文本编辑器编辑生成所需要的 3 个文件hello.h, hello.c以及main1.c。
程序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:main1.c
#include "hello.h"
int main()
{
hello("everyone");
return 0;
}
(3)用gcc编译器将 hello.c 编译.o文件
gcc -c hello.c
ls
2.静态库使用
(1)由.o 文件创建静态库。
静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。创建静态库用 ar 命令。
ar -crv libmyhello.a hello.o
(2)在程序中使用静态库
有三种方法:
方法一:
gcc -o hello main.c -L. –lmyhello
方法二:
gcc main.c libmyhello.a -o hello
方法三:
先生成 main.o:
gcc -c main.c
再生成可执行文件
gcc -o hello main.o libmyhello.a
我们删除静态库文件试试公用函数 hello 是否真的连接到目标文件 hello 中了。
rm libmyhello.a
3.动态库的使用
(1)由.o 文件创建动态库
动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀 lib,但其
文件扩展名为.so。
gcc -shared -fPIC -o libmyhello.so hello.o (-o 不可少)
(2)在程序中执行动态库
gcc -o hello main.c -L. -lmyhello或 #gcc main.c libmyhello.so -o hell
但是接下来./hello 会提示出错,因为虽然连接时用的是当前目录的动态库,但是运行时,是到/usr/lib 中找库文件的,将文件 libmyhello.so 复制到目录/usr/lib 中就 OK 了。
二、Linux 下静态库.a 与.so 库文件的生成与使用
1.准备工作
创建一个文件夹homework 2
用vim编辑器编写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<stdio.h>
#include"A.h"
int main()
{
print1(1);
print2("test");
exit(0);
}
2.静态库操作
2.1、生成目标文件(xxx.o)
gcc -c A1.c A2.c
2.2、生成静态库.a 文件
ar crv libafile.a A1.o A2.o
2.3、使用.a 库文件,创建可执行程序(若采用此种方式,需保证生成的.a 文件与.c 文件保
存在同一目录下,即都在当前目录下)
gcc -o test test.c libafile.a
ls
./test
在过程中我们发现程序存在错误,将test.c中的exit(0)改为return 0之后解决问题。
3.动态库操作
3.1、生成目标文件(xxx.o() 此处生成.o 文件必须添加"-fpic"(小模式,代码少),否则在生成.so文件时会出错。生成共享库.so文件
gcc -shared -fPIC -o libfile.so A1.o A2.o
ls
./test
三、在作业一的基础上进行拓展操作
1.在第一次作业的程序代码基础进行改编,除了x2x函数之外,再扩展写一个x2y函数(功能自定)。
1.1main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件
sub1.c(拓展)
float x2y(int a,int b)
{
float c=0;
c=a-b;
return c;
}
sub.c
float x2x(int a,int b)
{
float c=0;
c=a+b;
return c;
}
sub.h
#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif
main.c
#include<stdio.h>
#include"sub.h"
void main()
{
int a,b;
printf("Please input the value of a:");
scanf("%d",&a);
printf("Please input the value of b:");
scanf("%d",&b);
printf("a+b=%.2f\n",x2x(a,b));
printf("a/b=%.2f\n",x2y(a,b));
}
1.2并用gcc分别编译为3个.o 目标文件
gcc -c sub.c sub1.c
2.静态库操作
2.1将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序
ar crv libsub.a sub.o sub1,o
gcc -o main main.c libsub.a
2.2记录文件的大小
3.动态库操作
3.1将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序
gcc -shared -fPIC libsub.so sub.o sub1.o
gcc -o main main.c libsub.so
3.2记录文件大小
4.对比静态库和动态库文件的大小
通过比较我们可以看出动态库生成的文件比静态库要大。
参考资料
1.link