目录
(1)创建所需的hello.c,hello.h,main.c程序
一、用hello world作为例子
(1)创建所需的hello.c,hello.h,main.c程序
首先在终端中利用代码
mkdir hello
创建一个名为hello的文件夹
然后使用gedit文本编辑器生成hello.c,hello.h,main.c三个文件,三个文件源代码如下
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif //HELLO_H
hello.c
#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s\n", name);
}
main.c
#include "hello.h"
int main()
{
hello("world");
return 0;
}
(2)生成.o文件
利用代码
gcc -c hello.c
生成hello.o文件
(3)利用.o文件创建.a静态库
静态库文件名的命名规范是以 lib 为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将 创建的静态库名为 myhello,则静态库文件名就是 libmyhello.a。在创建和使用静态库时, 需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件 libmyhello.a。
ar -crv libmyhello.a hello.o
(4)在程序中使用静态库
在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用 gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀 lib,然后追加扩展名.a 得到的静态库文件名来查找静态库文件。
输入
gcc main.c libmyhello.a -o hello
即可生成目标程序hello,输入
./hello
即可输出函数结果
删除静态库文件libmyhello.a后,发现程序依旧可以正常运行,表明公用函数hello已经连接到目标文件hello中了
(5)创建.so动态库文件
动态库文件和静态库文件命名规范类似,不同在于文件拓展名,静态库文件为.a,动态库文件为.so
终端输入
gcc -shared -ffPIC -o libmyhello.so hello.o
创建动态库文件
(6)在程序中使用动态库
在程序中使用动态库和在程序中使用静态库方法类似,终端输入
gcc main.c libmyhello.so -o hello
创建成功动态库,使用./hello运行程序,发现报错了,报错代码如下
./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory
提示找不到动态库文件 libmyhello.so,这是因为程序在运行时, 会在/usr/lib 和/lib 等目录中查找需要的动态库文件,若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。我们将文件 libmyhello.so 复制到目录/usr/lib中,然后再次运行程序。
输入
mv libmyhello.so /usr/lib
然后再次报错
mv: 无法将'libmyhello.so' 移动至'/usr/lib/libmyhello.so': 权限不够
当出现权限不够的情况时,我们就需要进入root模式,终端中输入
su
回车后再输入密码,即可进入root模式
在root模式下再次输入
mv libmyhello.so /usr/lib
然后再次输入
./hello
即可成功运行目标程序hello
(
7)静态库和动态库优先级
当静态库和动态库同名时,gcc 命令将优先使用动态库
二、实例示范
详细过程可参考如上
(1)程序编写
程序如下
main.c
#include"sub1.h"
#include"sub2.h"
int main()
{
int x=2,y=3;
printf("%.5f\n",x2x(x,y));
printf("%f\n",x2y(x,y));
return 0;
}
sub1.c
#include"sub1.h"
float x2x(int a,int b)
{
float c;
c=(float)a/b;
return c;
}
sub1.h
#ifndef __SUB1_H
#define __SUB1_H
#include<stdio.h>
float x2x(int a,int b);
#endif
sub2.c
#include"sub2.h"
float x2y(int a,int b)
{
float d;
d=a+b;
return d;
}
sub2.h
#ifndef __SUB2_H
#define __SUB2_H
#include<stdio.h>
float x2y(int a,int b);
#endif
(2)生成静态库
(3)生成动态库
(4)静态库与动态库文件大小对比
静态库文件大小远小于动态库文件
三、总结
通过上述两个例子,熟悉了生成静态库和动态库的操作,通过gcc进行编译链接.o文件即可得到可执行文件,中途出现了一些小问题,都是一些例如输错代码的低级错误,或者可预知的问题,总体而言还行。
四、参考文献
gcc 生成 .a静态库和 .so动态库 - only_eVonne - 博客园