#一、前言
如果有公司需要使用你们产品的一部分功能(通过代码调用这些功能),如果不想提供源代码,那么就可以通过封装成库文件的形式提供给对方使用。本文主要介绍了生成动态库与静态库文件的过程、以及封装和使用库文件的方法。
#二、静态库.a与动态库.so的生成与区别
.o文件 :二进制目标文件,可用于打包成库文件也可以链接生成可执行文件;
c文件编译后链接,生成可执行文件

gcc  test1.c test2.c test3.c test_main.c -o test_main
./test_main


将.o目标文件链接生成可执行文件

gcc -c  test1.c test2.c test3.c test_main.c//编译成.o目标文件
gcc  test1.o test2.o test3.o test_main.o -o test_main_1//把.o文件链接成可执行文件
./test_main_1


源码test1.h

#include <stdio.h>void log_1();//函数在.h头文件中声明

源码test1.c

#include "test1.h"
//函数在.C文件中实现
void log_1(){printf("This is file test1!\n");
}

源码test2.h

#include <stdio.h>void log_2();

源码test2.c

#include "test2.h"void log_2(){printf("This is file test2!\n");
}

源码test3.h

#include <stdio.h>void log_3();

源码test3.c

#include "test3.h"void log_3(){printf("This is file test3!\n");
}

源码test_main.h

#include <stdio.h>#include "test1.h"//引入头文件
#include "test2.h"
#include "test3.h"void log_1();//声明test1.h中的函数void log_2();void log_3();

源码test_main.c

#include "test_main.h"
int main(int argc, char* argv[]){log_1();//调用test1.h中的函数log_2();log_3();return 0;
}

.a文件 :静态库文件,静态库在编译时已经被链接到目标代码中,运行程序不依赖该静态库文件;
优点:将程序使用的函数的机器码复制到最终的可执行文件中,提高了运行速度;如果库函数改变,整个程序需要重新编译
缺点:所有需用到静态库的程序都会被添加静态库的那部分内容,使得可执行代码量相对变多,占用内存和硬盘空间

ar rc libtest.a test1.o test2.o test3.o//把.o文件打包成.a的库文件
gcc test_main.c -L. -ltest -o test_main_a//链接生成可执行文件
./test_main_a//运行测试程序
rm libtest.a //删除静态库文件
./test_main_a//同样正常运行程序


.so文件:动态库文件,在程序运行的时候载入动态库文件,程序要正常运行必须依赖于它需要使用的动态库文件;
优点:只有在程序执行的时候, 那些需要使用的函数代码才被拷贝到内存中。动态库在内存中可以被被多个程序使用,又称之为共享库,节约了内存和磁盘空间,以时间效率去换取空间效率;当调用接口没改变,库文件发生改变重新编译,而调用的主程序可不用重新编译;
缺点:运行速度不及静态库文件;
静态库与动态库的选取使用,请结合自己的场景进行取舍,我不知道客户要使用的频率,我选择使用动态库的形式;
#三、.so库文件的封装以及使用
首先查看目录层次,可以看到就当前目录分别由一个lib的库目录、Makefile、ReadMe.txt、测试调用库函数的源码和用户使用的库头文件

ls -R

也可以安装tree工具,查看所有文件更有目录层次

sudo apt-get install tree//安装
sudo tree --help//查看命令选项
tree -a//列出当前目录的所有文件名(文件和文件夹)


最重要就是把lib里面的所有文件编译成一个.so的库文件;
lib库里的Makefile

OBJS:=adTorgb.cpp.o  descriptors.c.o  error.c.o  linux.c.o  satusbimage.cpp.o  usb.c.o#把所有[.c]文件编译成[.o]文件
#-fPIC; 代表编译为位置独立的代码,满足了不同的进程对所加载动态库的共享;
#-c; 表示只编译源文件但不链接;
#$<; 表示所搜索到与第一个相匹配的文件,即第一个[.c]文件;
#-o; 指定输出文件名;
#$@; 与[.c]文件相对应的[.o]文件;
#-I.; 需用到的头文件在本目录中找.
%.c.o:%.c gcc -fPIC -c $< -o $@ -I.%.cpp.o:%.cppg++ -fPIC -c $< -o $@ -I.#-shared: 该选项指定生成动态连接库
all:$(OBJS)@echo "Compile..."g++ -shared -fpic -o libsatusb.so $(OBJS)@echo "End"clean:rm -fr *.o *.so

对比封装lib库与测试目录satusbimage.h的区别,以下为封装库的头文件:

#ifndef _SATUSBIAMGE_H_
#define _SATUSBIMAGE_H_
#endif
#include <usb.h>
#include "color_tables_rgb.h"#define USB_VID         0x0547          //CY7C68014A的产商ID
#define USB_PID         0x0503          //CY7C68014A的产品ID#define EP0ADDR         0x01            //端口0地址,通道0
#define EP1ADDR         0x81            //端口1地址,通道1
#define EP2ADDR         0x02            //端口2地址,通道2
#define EP3ADDR         0x86            //端口3地址,通道3
#define USB_TIMEOUT     10000           //传输数据的时间延迟#define IR_ROW 288
#define COL 1024
#define IR_IMAGE_SIZE       IR_ROW*COL*2        //IR一帧图像的大小/**@find_device. We can find out the USB device that we need to use from USB bus. We need to open USB device for getting USB handle.  *@param   Void *@return  Non-null value indicates that the function is called successfully, and the function of return value is an USB device. */
struct usb_device* find_device();/**@open_device   We can obtain a handle from the USB device after function call,the handle can be used to the parameter of reading Usb data.*@param  <dev>  Dev  means that we will choose which USB device to open.*@return Non-null value indicates that the function is called successfully. and the function of return value is a USB handle.
*/
usb_dev_handle* open_device(struct usb_device* dev);/**@bulk_read_data. If you want to watch the image, please use the bulk_read_data function.*@parameter <handle> We read data from the USB handle.<data_ad> Data_ad is used to save collected image of ad value.<data_rgb> Data_rgb is used to save the having been disposed of RGB of image data.
*@return Value greater than zero indicates that the function is called successfully.
*/
int bulk_read_data(usb_dev_handle* handle, char* data_ad, _rgb_item* data_rgb);/*@close_usb_handle. When you do not keep watch on the image, please use the close_usb_handle function to close the usb device,the parameter device_handle is the open_device function's return value. *@parameter <handle> We will close the USB device through hanlde. the parameter device_handle is the open_device function's return value. *@return Value greater than zero indicates that the function is called successfully.
*/
int close_usb_handle(usb_dev_handle* handle);/*@set_level_value. To set the brightness of picture *@parameter <value> The value of brightness*@return Return true if the parameter value between 0 and 255,else return false
*/
bool set_level_value(int value);/*@set_span_value. To set the contrast of picture *@parameter <value> The value of contrast*@return Return true if the parameter value between 0 and 255,else return false
*/
bool set_span_value(int value);

以下是测试函数所用到的头文件;

#ifndef _SATUSBIMAGE_H_
#define _SATUSBIMAGE_H_
#endif
#include <usb.h>#define IR_ROW 288
#define COL 1024
#define IR_IMAGE_SIZE       IR_ROW*COL*2
struct _rgb_item
{unsigned char r;unsigned char g;unsigned char b;unsigned char reserved;
};
typedef struct _rgb_item rgb_item;/**@find_device. We can find out the USB device that we need to use from USB bus. We need to open USB device for getting USB handle.  *@param   Void *@return  Non-null value indicates that the function is called successfully, and the function of return value is an USB device. */
struct usb_device* find_device();/**@open_device   We can obtain a handle from the USB device after function call,the handle can be used to the parameter of reading Usb data.*@param  <dev>  Dev  means that we will choose which USB device to open.*@return Non-null value indicates that the function is called successfully. and the function of return value is a USB handle.
*/
usb_dev_handle* open_device(struct usb_device* dev);/**@bulk_read_data. If you want to watch the image, please use the bulk_read_data function.*@parameter <handle> We read data from the USB handle.<data_ad> Data_ad is used to save collected image of ad value.<data_rgb> Data_rgb is used to save the having been disposed of RGB of image data.
*@return Value greater than zero indicates that the function is called successfully.
*/
int bulk_read_data(usb_dev_handle* handle, char* data_ad, _rgb_item* data_rgb,unsigned char color_table);/*@close_usb_handle. When you do not keep watch on the image, please use the close_usb_handle function to close the usb device,the parameter device_handle is the open_device function's return value. *@parameter <handle> We will close the USB device through hanlde. the parameter device_handle is the open_device function's return value. *@return Value greater than zero indicates that the function is called successfully.
*/
int close_usb_handle(usb_dev_handle* handle);/*@set_level_value. To set the brightness of picture *@parameter <value> The value of brightness*@return Return true if the parameter value between 0 and 255,else return false
*/
bool set_level_value(int value);/*@set_span_value. To set the contrast of picture *@parameter <value> The value of contrast*@return Return true if the parameter value between 0 and 255,else return false
*/
bool set_span_value(int value);

通过对比发现,两个头文件并不一样,如果不想让一些信息透露给三方,就可以封装成库,给第三方用户提供需要调用的接口即可,具体的实现在lib库中的.cpp中;
测试函数文件夹中的Makefile


all:#-L./lib: 编译时到当前路径的lib文件夹中去需找libsatusb.so库文件gcc satimagetest.c -L./lib -lsatusb -o satimagetest#如果要运行编译完成的可执行文件,必须得设置下环境变量(执行程序时会去链接这个.so库文件,如果不设置环境变量,就找不到该库文件,程序执行失败),或者把生成的.so库文件拷贝到已设置的路径下(可以查环境变量LD_LIBRARY_PATH,但移植性不高)。
#export LD_LIBRARY_PATH=/opt/satImage/lib/:$LD_LIBRARY_PATH

库文件的封装就介绍到此。

Linux静态库.a与动态库.so的生成与区别、以及.so库文件的封装与使用相关推荐

  1. 关于Linux静态库和动态库的分析

    From: http://hi.baidu.com/bdccutysj/blog/item/5bae7f0202abac7c3912bb15.html 1.什么是库 在windows平台和linux平 ...

  2. Linux 静态库 动态库

    转自:http://blog.chinaunix.net/uid-26833883-id-3219335.html 一.什么是库 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. ...

  3. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

  4. Linux静态库和动态库学习总结

    一.废话 之前由于工作需要,要封装一个Linux加密解密转换的动态库,这个之前只做过Windows下面的,Linux下面还真没有做过,之后做了整一个晚上才算做好,不过其中也学到了不少东西,包括Linu ...

  5. 在Linux中创建静态库.a和动态库.so

    转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...

  6. libcurl linux 静态链接库_GCC 程序编译的静态链接和动态链接

    转自:Mr_Bluyee 在链接阶段中,所有对应于源文件的 .o 文件."-l" 选项指定的库文件.无法识别的文件名(包括指定的.o目标文件和.a库文件)按命令行中的顺序传递给链接 ...

  7. Linux静态库与动态库

    文章目录 一.源代码的组织 二.静态库 三.动态库 四.静态库与动态库的优缺点 1.优点 2.缺点 五.动态库的优缺点 1.优点 2.缺点 六.编译的优先级 七.版权声明 一.源代码的组织 我们通常把 ...

  8. Linux 静态库和动态库的生成及使用

    1.分文件编程 分模块的编程思想:假设一个项目需要用到网络.超声波.电机,程序不是都杂糅在同一个文件,而是将网络.超声波.电机需要调用的函数写在不同文件里,在主文件中直接调用即可. 好处: a.功能责 ...

  9. 【Linux静态库和动态库】

    Linux静态库和动态库 1. 编译与ELF格式 2. 库的基本概念 3.静态库的制作:(假设要将a.c.b.c制作成静态库) 4.静态库的常见操作 5.静态库的使用 6. 多个库的相互依赖 举例1. ...

  10. Linux 静态库和共享(动态)库的创建与使用详解

    文章目录 Linux 静态库和共享(动态)库 库的介绍 使用库有什么好处 库制作完成后, 如何给用户使用 静态库(static library) 静态库的制作 ar工具创建lib过程 静态库的使用 源 ...

最新文章

  1. 用grep命令查找文件中带特定扩展名的字符串
  2. PacketGetAdapterNames返回false
  3. Fiori里前后台ETAG处理
  4. PHP7内核基础知识之变量类型
  5. Linux 命令(73)—— ps 命令
  6. C++编程语言中类对象的赋值与复制介绍(三)
  7. Java中普通代码块,构造代码块,静态代码块执行顺序
  8. 快速阅读《构建之法》——构建之法阅读笔记01
  9. winserve2016 万能驱动网卡_windows server 2016 安装有线网卡驱动
  10. 前端面试题汇总(vue+html基础)最新最全
  11. 「PHP 是最好的语言」这个梗是怎么来的?
  12. Modal中的确认和取消按钮
  13. 实现景区门票计费系统(Java抽象类练习含GUI窗体组件)
  14. Oracle11g pl-sql developer安装包及教程
  15. 牛客题库—软件测试(一)
  16. python爬取boss直聘招聘信息_Python 爬取boss直聘招聘信息!
  17. java二分排序法原理_Java常见排序算法详解—— 二分插入排序
  18. 【松岩早盘视点】2019-09-30
  19. 做自媒体没素材怎么办?
  20. 转:传说中破解基础----背的滚瓜烂熟差不多就会破解

热门文章

  1. 计算机存储选板选片,2019考研计算机知识要点:存储器芯片
  2. start.sh命令文件优雅地启动jar包
  3. 转贴:适合程序员的健康作息时间表
  4. userdel 命令
  5. 前端 实现吸顶的三种方式
  6. android mp3播放器学习之预备知识1:activity
  7. java计算机毕业设计古玩玉器交易系统MyBatis+系统+LW文档+源码+调试部署
  8. 进阶篇|游戏代理工作室如何更好的创收?
  9. YOLOv5的Tricks | 【Trick14】YOLOv5的val.py脚本的解析
  10. 【HDU 1495】非常可乐(BFS)