用gcc生成静态库和动态库并链接生成可执行文件
一、用gcc生成静态库和动态库
1.源程序准备
创建并以以下名字命名文件:
-
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.将hello.c编译成.o文件
gcc-c Hello.c //进行编译 ls //查看当前目录内是否生成Hello.o文件
3.生成与使用静态库
ar-crv libHello.a Hello.o
gcc -o Hello main.c -L. -lHello
gcc-o main.c libHello.a -o Hello
main.o gcc -c main.c
gcc -o Hello main.c libHello.a
验证静态库的特点。
在删除静态库后运行可执行文件,程序依旧正常运作。这表明静态库不影响程序的运行,也表明静态库在程序编译时就已经与代码链接。
rm libHello.a
4.生成与使用动态库
(1)创建动态库
gcc -shared -fPIC -o libHello.so Hello.o
(2)执行动态库
sudo mv libmyhello.so /usr/lib //启用管理员权限移动文件到对应文件夹内,否则无法找到文件执行
gcc -o Hello main.c -L. -lHello
gcc编译得到.o文件 gcc -c Hello.c
创建静态库 ar -crv libHello.a Hello.o
创建动态库 gcc -shared -fPIC -o libHello.so Hello.o
使用库生成可执行文件 gcc -o Hello main.c -L. -lHello
执行可执行文件 ./Hello
此处出现错误。当静态库与动态库同时存在,系统将优先使用动态库。
5.实例一
(1)代码
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");
return 0;
}
(2)命令
ar crv libfile.a A1.o A2.o
gcc -o test test.c libfile.a //使用静态库
gcc -shared -fPIC -o libfile.so A1.o A2.o
gcc -o test test.c libfile.so //使用动态库
6.实例二
(1)代码
sub1.c
float x2x(int a,int b)
{
float c=0;
c=a+b;
return c;
}
sub2.c
float x2y(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));
}
(2)命令
gcc -c sub1.c sub2.c
ar crv libsub.a sub1.o sub2.o
gcc -o main main.c libsub.a //静态库
gcc -shared -fPIC libsub.so sub1.o sub2.o
gcc -o main main.c libsub.so //动态库
生成文件比较
通过比较可以看出静态库比动态库小很多。
二、实操:c文件与o文件生成及静动态库链接转化可执行文件
1.程序
main.c
#include"sub1.h"
#include"sub2.h"
#include<stdio.h>
int main()
{
int x=2,y=9,n;
printf("%d/%d=%.2f\n",y,x,x2x(x,y));
printf("请输入斐波那契的第n项值:");
scanf("%d",&n);
printf("斐波那契数列第%d为%d\n",n,x2y(n));
return 0;
}
sub1.h
#ifndef __SUB1_H
#define __SUB1_H
float x2x(int a,int b);
#endif
sub1.c
#include "sub1.h"
/*******************/
/* 参数:a */
/* 参数:b */
/* 返回值:b/a */
/*******************/
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);
#endif
sub2.c
#include "sub2.h"
int x2y(int n)
{
int a=1,b=1,i;
long c=0;
if(n<3) return 1;
else
{
for(i=0;i<=n-3;i++)
{
c=a+b;
a=b;
b=c;
}
return c;
}
}
2.生成静态库文件
gcc -c main.c sub1.c sub2.c
ar -crv libx2.a sub1.o sub2.o
gcc main.o libx2.a -o main
测试静态库是否连接成功
3.链接动态库文件
gcc -shared -fPIC -o libx2.so sub1.o sub2.o
gcc main1.o libx2.so -o main
ll
sudo mv libx2.so /usr/lib
./main