本例程设计知识点:

  • 读取hidraw1设备数据
  • 子线程应用
  • 动态库的制作,及动态加载
  • 回调函数的注册和使用

opos.c文件源码:

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // for close
#include <string.h>#include <stdlib.h>
#include <pthread.h>
#include "opos.h"#define OposDisplayTest          1
#define ReadOposDisplayTest     1typedef void (*P_ShowBarcode)(char *str) ;//定义函数指针类型
P_ShowBarcode m_ShowBarcode = NULL;//定义一个函数指针 m_ShowBarcodeint fd=0, CloseFlag=0;
pthread_t id;//定义线程ID/*******************************************************************************
* Function Name  : reg_opos
* Description    : opos注册函数,用于注册回调显示条码的函数
* Input          : fun:回调显示的函数指针
* Output         : None
* Return         : None
*******************************************************************************/
void reg_opos(void * fun)
{m_ShowBarcode = (P_ShowBarcode)fun;
}/*******************************************************************************
* Function Name  : open_opos
* Description    : 打开opos函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void open_opos(void)
{void *arg = NULL;//定义一个空指针int ret;fd = open("/dev/hidraw1", O_RDWR);#ifdef OposDisplayTestprintf("fd = %d \n", fd);
#endifif(fd<0){
#ifdef  OposDisplayTestprintf("Open error2\n");
#endif}else{
#ifdef  OposDisplayTestprintf("Open ok\n");
#endifret=pthread_create(&id,NULL,(void *) ReadOposData,(void*)(&arg));if(ret!=0){
#ifdef  OposDisplayTestprintf ("Create pthread error!\n");
#endifexit (1);}}
}/*******************************************************************************
* Function Name  : close_opos
* Description    : 关闭opos函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void close_opos(void)
{CloseFlag=1;//关闭标志置1pthread_join(id,NULL);#ifdef  OposDisplayTestprintf("close\n");
#endifclose(fd);
}/*******************************************************************************
* Function Name  : ReadOposData
* Description    : 读取opos数据的函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ReadOposData(void *arg)
{char barcode[2048];int count=64, read_num=0;int remain_len=0, save_len=0, code_len=0;unsigned char buffer[64];CloseFlag=0;//清空关闭标志while(CloseFlag==0){
#ifdef  ReadOposDisplayTestprintf("read...\n");
#endifmemset(barcode, 0, sizeof(barcode));//清零code_len = 0;remain_len = 0;save_len = 0;read_num = read(fd,buffer,count);//读取opos数据包if (read_num<0){
#ifdef  ReadOposDisplayTestprintf("read fail\n");
#endif}else{code_len = buffer[0] + (buffer[1]<<8);//获取整个数据包的长度remain_len = code_len+2;//包头的长度不包含最后两个字节的校验码#ifdef  ReadOposDisplayTestprintf("remain_len = %d\n", remain_len);
#endifif(remain_len <= read_num)//一个opos包接收完所有数据{memmove(barcode, buffer+4, remain_len-4);//解析出条码数据save_len += remain_len-4;remain_len = 0;}else{memmove(barcode, buffer+4, read_num-4);//解析出条码数据save_len += read_num-4;remain_len -= read_num;while(remain_len){memset(buffer, 0, sizeof(buffer));//清零read_num = read(fd,buffer,count);//读取opos数据包if (read_num<0){
#ifdef  ReadOposDisplayTestprintf("read fail\n");
#endif}if(remain_len>=read_num)//数据包中不包含最后两个字节的校验符。{memmove(barcode+save_len, buffer, read_num);//解析出条码数据save_len += read_num;remain_len -= read_num;}else{memmove(barcode+save_len, buffer, remain_len);//解析出条码数据save_len += remain_len;remain_len = 0;}}}#ifdef   ReadOposDisplayTestprintf("save_len = %d\n", remain_len);
#endifbarcode[save_len-2] = '\0';//设置字符串换行符m_ShowBarcode(barcode);//回调main函数中的函数,用于显示条码}}
}
//说明:此函数涉及到从设备的打包格式中提出数据。

opos.h文件源码:

#ifndef OPOS_H
#define OPOS_Hvoid reg_opos(void * fun);
void open_opos(void);
void close_opos(void);void ReadOposData(void *arg);#endif

main.c文件源码:

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <signal.h>
#include <errno.h>
#include "opos.h"int listnum =0;/*******************************************************************************
* Function Name  : error_quit
* Description    : 输出错误信息并退出
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void error_quit(const char *str)
{        fprintf(stderr, "%s\n", str);     exit(1);
}   /*******************************************************************************
* Function Name  : ShowBarcode
* Description    : 显示条码的函数
* Input          : str需要显示的条码字符串的指针
* Output         : None
* Return         : None
*******************************************************************************/
void ShowBarcode(char *str)
{        listnum ++;printf("%d: %s\n", listnum,str);
}/*******************************************************************************
* Function Name  : main
* Description    : 主函数
* Input          : argc:未调用,argv:未调用
* Output         : None
* Return         : 0
*******************************************************************************/
int main(int argc, char * argv [ ])
{void *plib;                    //指向so文件的指针  typedef void (*FUN_REG_OPOS)(void*);  typedef void (*FUN_OPEN_OPOS)(); typedef void (*FUN_CLOSE_OPOS)();  FUN_REG_OPOS funRegOpos = NULL;    //函数指针  FUN_OPEN_OPOS funOpenOpos = NULL;      //函数指针 FUN_CLOSE_OPOS funCloseOpos = NULL;     //函数指针 char command_data = '0';//打开so文件  //为了方便演示,我将库文件和可执行文件放在同一个目录下  plib = dlopen("./libopos.so", RTLD_NOW | RTLD_GLOBAL);  if( NULL == plib )  error_quit("Can't open the libopos.so");  funRegOpos = dlsym(plib, "reg_opos");  if( NULL == funRegOpos )  error_quit("Can't load function 'reg_opos'");  funOpenOpos = dlsym(plib, "open_opos");  if( NULL == funOpenOpos )  error_quit("Can't load function 'open_opos'"); funCloseOpos = dlsym(plib, "close_opos");  if( NULL == funCloseOpos )  error_quit("Can't load function 'close_opos'"); //注册函数funRegOpos((void*)ShowBarcode);//打开oposfunOpenOpos();   while(1){scanf("%c",&command_data);if(command_data=='c'){printf("Close opos!\n");break;}}//关闭oposfunCloseOpos();//关闭so文件  dlclose(plib);  printf("end!\n");return 0;
}

ubuntu终端运行:

命令1:gcc opos.c -fPIC -shared -o libopos.so -lpthread

作用:生成动态库文件 opos.c。

命令2:gcc main.c -o main -ldl

作用:编译main.c文件,调用了动态库,增加“-ldl”。

命令3:sudo ./main

作用:使用管理员权限运行main函数。

展示效果:

Linux下,接收opos数据的例程相关推荐

  1. linux数据同步技术比较,linux下实现web数据同步的四种方式(性能比较)教程.docx

    linux下实现web数据同步的四种方式(性能比较)教程 实现web数据同步的四种方式=======================================1.nfs实现web数据共享2.rs ...

  2. mysql安装设置数据目录下,linux下安装mysql数据+配置

    <linux下安装mysql数据+配置>由会员分享,可在线阅读,更多相关<linux下安装mysql数据+配置(2页珍藏版)>请在人人文库网上搜索. 1.Redhat下安装My ...

  3. linux下发送hex数据的串口调试软件,linux下模拟串口向计算机发送数据

    本人新手   从网上找了个串口通信程序改了改  本来是用单片机向串口发数据测试   但现在手头没有   请问有没有什么别的方法可以用? 非常感谢 | 一.使用工具 Windows XP 串口调试器 C ...

  4. linux下读取ntfs数据,在Linux中读取NTFS分区上的数据

    在Linux中读取NTFS分区上的数据 在有些情况下,系统需要访问本地NTFS分区上的数据,也可能需要访问网络上NTFS文件格式的数据.而使用mount -t挂载文件系统时,系统报告不支持NTFS错误 ...

  5. linux恢复到硬盘分区,linux下恢复硬盘分区数据

    今天下午在linux下删除操作,想安装oracle数据库,整理硬盘的时候用fdisk重新划分分区,我的硬盘分区表是这样的:QUOTE:# fdisk -l /dev/hda Disk /dev/hda ...

  6. Oracle Golden Gate 使用小结:Windows下的Oracle – Linux下Kafka的数据同步

    1.首先,需要先了解OGG的基本概念:ogg概念与机制 2.这篇小结里的源端是Windows下的Oracle(192.168.88.37),目标端是Linux下的Kafka(10.53.127.126 ...

  7. Linux下C/C++数据包嗅探(Sniffer)

    我们知道当任何数据必须通过计算机网络传输时,它在发送方节点被分解成更小的单元,称为数据包.在接收方节点以原始格式重新组装.它是计算机网络上最小的通信单元.它也被称为块.段.数据报或单元.通过计算机网络 ...

  8. linux下实现web数据同步的四种方式(性能比较)

    实现web数据同步的四种方式 ======================================= 1.nfs实现web数据共享 2.rsync +inotify实现web数据同步 3.rs ...

  9. linux下下载fnl数据,python处理FNL数据的grib文件和nc文件(纬度存储的问题)

    python处理FNL数据的grib文件和nc文件(纬度存储的问题) python处理FNL数据的grib文件和nc文件(纬度存储的问题) 在使用python处理FNL数据时,2007年及之前的数据存 ...

最新文章

  1. python开发视频播放器_python视频播放器
  2. python运行非常慢的解决-python执行太慢
  3. c++STL容器的string
  4. MySQL分组查询的介绍
  5. android fragment动态添加,Android动态添加Fragment
  6. 【矩阵乘法】OpenJ_POJ - C17F - A Simple Math Problem
  7. Pytorch采坑记录:每隔num_workers个iteration数据加载速度很慢
  8. 神奇的python(一)之python脚本调用shell常用方法
  9. 使用php://input
  10. 达观杯文本智能处理(6)
  11. 翻译:道路机动车辆驾驶自动化系统相关术语的分类和定义 J3016_202104
  12. 计算机系统导论与计算机导论,计算机系统导论之学习心得
  13. 大屏可视化之适配和布局
  14. 如何在github上创建自己的个人网站
  15. 云计算工程师必备技能图谱
  16. Python | Python保存高维数组array,Python用pandas将numpy保存csv文件,Python保存3维数组
  17. A03-arcgis无法统计地块面积常见问题及解决方案
  18. 怎么看自己的maven本地仓库在那里
  19. 【STM32—MDK-ARM】勾选了“Reset and Run”却不起作用,怎么办?
  20. Instructional Technology Notes at random

热门文章

  1. 计算机中日期连接符号,电脑时间不能同步,在命令提示符里输入w32tm
  2. DELL 7080MFF 黑苹果安装,优化
  3. Java代码生成图片验证码
  4. SAX 解析XML文件:将XML转换成Java对象
  5. PostgreSQL中的距离计算问题 ST_Length
  6. Psp软件开发过程定位设计
  7. 一年级计算机课ppt,一年级信息技术全部课程PPT课件.ppt
  8. 重磅 | GitHub私有仓库从此免费,微软要赢开发者的心
  9. Java实现面向切面编程(AOP)
  10. 解决:运行pytest时,报错:'TestCaseFunction' object has no attribute 'get_marker'