静态库于动态库
-
什么是库
库 是代码的一种二进制的封装形式在其他源码中,直接调用,但是又看不到具体的实现方式 库的封装有利于模块化设计,而且只要接口设计合理 改变库的实现,不影响使用库的源码 优点: 1)不会泄露源代码 2)运行时可以直接调用 3)方便程序的更新和维护 库分为两种: 动态库 静态库
-
动态库
-
动态库的封装步骤:
-
编辑源代码(一般来说,库的源码中是不包含main函数)
xxx.c 功能函数的实现
xxx.h 函数、类型的声明 “接口文件” -
生成动态库
arm-linux-gcc -shared -fpic -o libxxx.so xxx.c …
-shared 生成动态库(共享库) -fpic 与位置无关 -o 指定生成的库的名字 把xxx.c 等源代码文件列表,编译生成动态库,名叫libxxx.so (动态库的命名:一般是 以lib开头,以.so结尾)
-
把 库 和 头文件 拷贝给他人使用
main.c #include "xxx.h" <------ libxxx.so xxx.h (arm-linux-)gcc main.c -o main //直接编译会报错 指定 头文件 和 库的搜索路径 -I //指定头文件的搜索路径,可以指定多个-I -L //指定库的搜索路径,可以指定多个-L -l //指定库的名字(除去lib和.so),可以指定多个-l ---> arm-linux-gcc main.c -o main -I ./ -L ./ -lxxx 当去运行这个可执行文件时,首先会找它依赖的库 找不到就会报错 ./main: error while loading shared libraries: libsum.so: cannot open shared object file: No such file or directory Linux有一个环境变量 LD_LIBRARY_PATH //LD loading加载 //LIBRARY 库 //PATH 路径 配置环境变量 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: + 需要指定的路径 例子: export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/hgfs/CS22268/04_交叉开发/03_动态库和静态库/code 或者 把库拷贝到标准的库的搜索路径下 cp libxxx.so /usr/lib/ 注意: 在使用动态库时,在可执行文件中做了一个标记,表示这个可执行文件可能需要用到这个库 如果需要在开发板上运行,那么也要把动态库下载到开发板上, 必要时,还需要配置 加载库的路径 LD_LIBRARY_PATH
-
-
-
静态库
-
使用静态库的步骤
-
编辑源代码
xxx.c xxx.h
-
把源代码 编译生成 .o文件
xxx.c ---> xxx.o (arm-linux-)gcc -c xxx.c -o xxx.o
-
用 ar 命令把所有的.o 文件 打包生成一个静态库
(arm-linux-)ar -rc libxxx.a xxx.o .... 把xxx.o等.o文件列表,打包生成一个静态库,名为libxxx.a (静态库的命名:一般是 以lib开头,以.a结尾)
-
把 静态库 和 头文件 拷贝给他人使用
main.c #include "xxx.h" <--- libxxx.a xxx.h (arm-linux-)gcc main.c -o main -I ./ -L ./ -lxxx
-
-
-
静态库于动态库的区别
-
对于动态库来说
编译生成可执行文件时,并没有把动态库的内容拷贝到可执行文件中,
只是做了一个标记,表示这个可执行文件可能需要用到这个动态库,
这样的话,运行这个可执行文件时,需要把动态库也下载到开发板上,
必要时,还需要配置 加载库的路径 LD_LIBRARY_PATH -
对于静态库来说
编译生成可执行文件时,就会把静态库的内容全部拷贝到可执行文件中,运行时,直接运行即可,
如果在开发板上运行,也不需要把静态库下载过去 -
动态库的两个明显优势
(1)当接口变化时,更新动态库,不需要 重新编译 依赖这个库的工程文件
如果是静态库,进行了修改,就需要 重新编译 依赖这个库的工程文件(2)运行的时候,动态库在内存中只有一份拷贝
而静态库,则会有多份拷贝(看有多少个程序在使用它)
-