一、库的使用
1.gcc生成静态库与动态库
函数库分为静态库和动态库,静态库:在程序编译时会被连接到目标代码中,程序运行时不需要静态库。动态库:有时也被称为共享库,在程序编译时不会连接到目标代码,而是在程序运行时载入,下面进行举例:
(1)创建代码hello.h,hello.c,main.c.
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif
hello.c
#include<stdio.h>
void hello(const char *name)
{
printf("Hello"%s!\n,name);
}
main.c
#include<hello.h>
int main()
{
hello("everyone");
return 0;
}
(2)编译得到.o文件
gcc -c hello.c
(3)静态库的创建及使用
创建静态库:使用ar工具
ar -crv libmyhello.a hello.o
静态库使用:
gcc -o hello main.c -L. -lmyhello
此时已将静态库连接到当前目录,下面执行
./hello
再删除静态库:
rm libmyhello.a
再次执行:./hello
可以看出编译后静态库已经不需要了,无论存在与否都对结果无影响
(4)动态库的创建及使用
创建工具:gcc
gcc -shared -fPIC -o libmyhello.so hello.o
此时不能直接使用,在运行时会报错,原因是缺少对应文件,我推荐的解决方法是将文件复制到当前目录
sudo cp libmyhello.so /usr/lib
再运行,结果与静态库一致。
2.Linux1下.a与.so库文件的生成与使用
(1)创建代码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).a与.so文件创建与使用。由于我编译过一次,所以会出现test 但步骤不变
3.实操
(1)创建代码sub1.c,sub2.c,sub.h main.c
sub1.c
#include<stdio.h>
float x2x(int a,int b)
{
float i;
i=(float)a/b;
return i;
}
sub2.c
#include<stdio.h>
float x2y(int a,int b)
{
float j;
j=(float)a/b+a;
return j;
}
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()
{
float i,j;
i=x2x(a,b);
j=x2y(a,b);
printf("a/b=%.2f\n",i);
printf("a/b+a=%.2f\n",j);
}
通过ll命令可发现.a文件用量为2720,.so文件用量为7496,静态库比动态库小很多。
二、EFF文件格式
示例文件test.c:
#include<stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
该程序可一步到位执行:
gcc test.c -o test
但实质上分为以下四阶段进行,包括预处理、编译、汇编、连接
预处理:
gcc -E test.c
生成.i文件
输出为预处理后代码
编译:
gcc -S test.i -o test.s
生成.s文件
汇编:
gcc -c test.s -o test.o
生成.o文件
连接:
gcc test.o -o test
生成程序test
此时test为EFF文件,可对其进行以下操作
readelf -S test
再进行反汇编:
objdump -D test
最后显示源代码:
gcc -o test -g test.c
objdump -S test