函数:某些功能代码的封装,可能通过将函数声明放置头文件当中,给其它文件进行调用,那么封装的函数可见(可以使用代码实现的过程),称为开源。封装的函数不可见(将代码实现的过程进行封装动静态库),称为闭源(不开源)。
linux下有动静态库
linux以.a结尾的是静态库,以.so结尾的为动态库; linux下默认的库路径/lib
静态库:在编译时以函数叠加的方式增加到代码中,使用运行,可脱离库运行。使用静态库生成的可以文件相对较大,内存开销大,但是运行效率高。
动态库:在编译时以链接的方式增加到代码中,当需要库函数时,才调用,使用动态库生成的可以文件相对较小,内存开销小,但是运行效率略低。
使用ar工具创建静态库的时候需要两个参数:
参数c:创建一个库,不管库是否存在,都将创建。
参数r:在库中插入模块 (替换)。默认新的成员添加在库的结尾处,如果模块名已经在库中存在,则替换同名的模块。
(1)在某个目录下编写三个.c(main.c add.c sub.c)文件及两个.h(add.h sub.h)文件,文件参与project。这个工程必须是编译通过才能制作库。
main.c
/*main.c*/
#include
#include "sub.h"
#include "add.h"
int main(void)
{
int num, a, b;
printf("请输入两个正整数:");
scanf("%d%d", &a, &b);
num = add(a, b);
printf("两数之和:%d\n", num);
num = sub(a, b);
printf("两数之差:%d\n", num);
return 0;
}
/*add.c*/
#include "add.h"
int add(int a, int b)
{
int num;
num = a+b;
return num;
}
/*sub.c*/
#include "sub.h"
int sub(int a, int b)
{
int num;
num = a-b;
return num;
}
/*sub.h*/
#ifndef __SUB_H
#define __SUB_H
#include
int sub(int a, int b);
#endif
/*add.h*/
#ifndef __ADD_H
#define __ADD_H
#include
int add(int a, int b);
#endif
gec@ubuntu:~/Desktop/project$ gcc *.c -o main
或者
gec@ubuntu:~/Desktop/project$ gcc main.c add.c sub.c -o main
(2)将需要封装.c文件生成.o文件
gec@ubuntu:~/Desktop/project$ gcc -c add.c sub.c
(3).o文件生成.a(静态库文件), ar:生成静态库命令
ar -rc xxx.a xxx.o xxx.o
gec@ubuntu:~/Desktop/project$ ar -rc libmylib.a add.o sub.o
静态库命名:lib+库名(自定义)+.a 比如:libmylib.a
(4)运用
gec@ubuntu:~/Desktop/project$ gcc main.c -o main libmylib.a
gec@ubuntu:~/Desktop/project$ ./main
请输入两个正整数:85 47
两数之和:132
两数之差:38
假设静态库在某个路径(/home/gec/libmylib.a ),编译方法:
gec@ubuntu:~/Desktop/project$ gcc main.c -o main /home/gec/libmylib.a
(1)在某个目录下编写三个.c(main.c add.c sub.c)文件及两个.h(add.h sub.h)文件,文件参考project里面代码。这个工程必须是编译通过才能制作库。
gec@ubuntu:~/Desktop/project$ gcc *.c -o main
或者
gec@ubuntu:~/Desktop/project$ gcc main.c add.c sub.c -o main
(2)将.c文件生成.so文件
gec@ubuntu:~/Desktop/project$:gcc -fpic -shared xxx.c xxx.c -o libxxx.so
-fpic:表示编译为独立的代码块
-shared:指定生成动态库
libxxx.so:库名
动态库命名::lib+库名(自定义)+.so+(版本号)
例如:
gec@ubuntu:~/Desktop/project$ gcc -fpic -shared sub.c add.c -o libmylib.so
(2)使用动态库进行编译(直接编译)
gec@ubuntu:~/Desktop/project$ gcc main.c -o main libmylib.so
或者
gec@ubuntu:~/Desktop/project$ gcc main.c -o main ./libmylib.so (./表示当前路径)
或者
gec@ubuntu:~/Desktop/project$ gcc main.c -o main /home/gec/libmylib.so
(3)使用动态库进行编译(间接编译)
假设动态库文件在:/home/gec目录下
gec@ubuntu:~/Desktop/project$ gcc main.c -o main -L /home/gec/ -lmylib
gcc main.c -o main -L /home/gec/ -lmylib
-L :指定库的路径标志
/home/gec/ :库所在的路径
-l :链接库标志
mylib :库名
假设头文件(/home/gec/include)与main.c不同的路径,编译方法:
gcc main.c -o main -L /home/gec/ -lmylib -I /home/gec/include/
说明
-I :指定头文件的路径标志
/home/gec/include/:关文件路径
或者将库存文件放置在系统默认的库路径下
/lib 或者/usr/lib
gec@ubuntu:~/Desktop/project$ sudo cp /home/gec/libmylib.so /usr/lib
gec@ubuntu:~/Desktop/project$ gcc main.c -o main -lmylib
使用动态库编译的程序运行方法
**方法1:**将动态库放置到系统默认的库路径中
/lib
gec@ubuntu:~/Desktop/project$:sudo cp libmylib.so /lib
gec@ubuntu:~/Desktop/project$: sudo cp libmylib.so /lib
gec@ubuntu:~/Desktop/project$: ./main
请输入两个正整数:45 25
两数之和:70
两数之差:20
**方法2:**将动态库放置在任何位置,在系统的启动文件中添加环境变量即可,然后环境变量生效。
gec@ubuntu:~/Desktop/project$: gedit ~/.bashrc
在文件最后一行添加
export LD_LIBRARY_PATH=/home/gec:$LD_LIBRARY_PATH
执行下面命令,使环境变量生效
gec@ubuntu:~/Desktop/project$: source ~/.bashrc
如果上面命令不生效,关闭终端重启终端即可。
gec@ubuntu:~/Desktop/project$ ./main
请输入两个正整数:45 25
两数之和:70
两数之差:20
这里是基于linux下的x86平台的库制作及运行,如果是运行的平台是arm,将对应的工具链换成对应的:arm-linux-gcc即可,本人已经测试过,可用。