之前一直对动态库静态库这个概念很模糊,到了快找实习的时候,决定认真地学一遍,毕竟这到了公司之后会经常用到。
下面是我自己学习的一些笔记
1.动态库(.so)和静态库(.a)的区别
简单地来说(个人的理解,可能有偏差,希望大神指正):
1、在编译生成二进制文件时,动态库的源代码没有放到二进制文件中,编译时需要告诉编译器动态库的路径
2、在编译生成二进制文件时,静态库的源代码加载进去一起编译
静态库有个不好的地方,当静态库很大时,加载进去就显得很费时
2.制作前的说明
首先来看一下下面代码:
------------平常写的main.c-------------
#include <stdio.h>
#include "add.h"
int main()
{
int c=add(10,20);
printf("c=%d",c);
}
------------------函数模块化(即函数体,要制作成库的.c文件)add.c------
#include "add.h"
int add(int a,int b) //这里只有函数的实现,函数的定义放到头文件中
{
return a+b;
}
---------------头文件add.h-------------------------------
#ifndef _ADD_H_ //防止头文件重复定义
#define _ADD_H_
#include <stdio.h>
int add(int a,int b);
#endif
=========================
我们来tree一下这3个文件的位置,其中lib文件夹里面放的是我们即将做的库
3.动态库、静态库的制作
1.动态库的制作
1)找到函数定义的地方,将.c文件编译成.o文件(.o文件里面的是机器语言):
gcc -c add.c -o add.o
2)把.o文件编译生成libadd.so(注意lib是前缀,add才是库名,.so是后缀):
gcc -fPIC -shared add.o -o libadd.so
也可以一步到位:gcc -fPIC -shared add.c -o libadd.so
注意我这里头文件没有跟.c文件放同一个目录,所以要指定一下头文件的位置gcc -fPIC -shared add.o -o libadd.so -I../include (等一下我们讲指定的问题)
3)把生成的库放到/lib下:
4)编译命令
gcc main.c -o main -Iinclude/ -Llib/ -ladd
有人可能会文后面的是啥
这里说明一下:
-I(大写的i Include):告诉编译器在哪里找头文件
-L(库Lib):告诉编译器在哪里找库文件
-l (小写的L):要链接哪个动态库,写库名(即add)
编译完后又有个问题
说加载库文件时找不到这个库,这是因为系统默认在$LD_LBRARY_PATH这里找
我们可以把库路径添临时加进去:
要永久设置则修改文件 gedit ~/.bashrc 加到变量上去
或者直接把库复制到~/lib下
这样运行就没问题了!!
2.静态库的制作
1)找到函数定义的地方,将.c文件编译成.o文件(.o文件里面的是机器语言):
gcc -c add.c -o add.o
2)把.o文件编译生成libadd.a(注意不能一步到位,只能从.o制作静态库):
ar -rc libadd.a add.a
3)把库文件放到与main.c一个文件夹,编译
gcc main.c libadd.a -o main -Iinclude (因为我的头文件不在一个地方,所以得指定)
注意:main.c 和libadd.a顺序不能调换