Linux下,接收opos数据的例程
本例程设计知识点:
- 读取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数据的例程相关推荐
- linux数据同步技术比较,linux下实现web数据同步的四种方式(性能比较)教程.docx
linux下实现web数据同步的四种方式(性能比较)教程 实现web数据同步的四种方式=======================================1.nfs实现web数据共享2.rs ...
- mysql安装设置数据目录下,linux下安装mysql数据+配置
<linux下安装mysql数据+配置>由会员分享,可在线阅读,更多相关<linux下安装mysql数据+配置(2页珍藏版)>请在人人文库网上搜索. 1.Redhat下安装My ...
- linux下发送hex数据的串口调试软件,linux下模拟串口向计算机发送数据
本人新手 从网上找了个串口通信程序改了改 本来是用单片机向串口发数据测试 但现在手头没有 请问有没有什么别的方法可以用? 非常感谢 | 一.使用工具 Windows XP 串口调试器 C ...
- linux下读取ntfs数据,在Linux中读取NTFS分区上的数据
在Linux中读取NTFS分区上的数据 在有些情况下,系统需要访问本地NTFS分区上的数据,也可能需要访问网络上NTFS文件格式的数据.而使用mount -t挂载文件系统时,系统报告不支持NTFS错误 ...
- linux恢复到硬盘分区,linux下恢复硬盘分区数据
今天下午在linux下删除操作,想安装oracle数据库,整理硬盘的时候用fdisk重新划分分区,我的硬盘分区表是这样的:QUOTE:# fdisk -l /dev/hda Disk /dev/hda ...
- Oracle Golden Gate 使用小结:Windows下的Oracle – Linux下Kafka的数据同步
1.首先,需要先了解OGG的基本概念:ogg概念与机制 2.这篇小结里的源端是Windows下的Oracle(192.168.88.37),目标端是Linux下的Kafka(10.53.127.126 ...
- Linux下C/C++数据包嗅探(Sniffer)
我们知道当任何数据必须通过计算机网络传输时,它在发送方节点被分解成更小的单元,称为数据包.在接收方节点以原始格式重新组装.它是计算机网络上最小的通信单元.它也被称为块.段.数据报或单元.通过计算机网络 ...
- linux下实现web数据同步的四种方式(性能比较)
实现web数据同步的四种方式 ======================================= 1.nfs实现web数据共享 2.rsync +inotify实现web数据同步 3.rs ...
- linux下下载fnl数据,python处理FNL数据的grib文件和nc文件(纬度存储的问题)
python处理FNL数据的grib文件和nc文件(纬度存储的问题) python处理FNL数据的grib文件和nc文件(纬度存储的问题) 在使用python处理FNL数据时,2007年及之前的数据存 ...
最新文章
- python开发视频播放器_python视频播放器
- python运行非常慢的解决-python执行太慢
- c++STL容器的string
- MySQL分组查询的介绍
- android fragment动态添加,Android动态添加Fragment
- 【矩阵乘法】OpenJ_POJ - C17F - A Simple Math Problem
- Pytorch采坑记录:每隔num_workers个iteration数据加载速度很慢
- 神奇的python(一)之python脚本调用shell常用方法
- 使用php://input
- 达观杯文本智能处理(6)
- 翻译:道路机动车辆驾驶自动化系统相关术语的分类和定义 J3016_202104
- 计算机系统导论与计算机导论,计算机系统导论之学习心得
- 大屏可视化之适配和布局
- 如何在github上创建自己的个人网站
- 云计算工程师必备技能图谱
- Python | Python保存高维数组array,Python用pandas将numpy保存csv文件,Python保存3维数组
- A03-arcgis无法统计地块面积常见问题及解决方案
- 怎么看自己的maven本地仓库在那里
- 【STM32—MDK-ARM】勾选了“Reset and Run”却不起作用,怎么办?
- Instructional Technology Notes at random
热门文章
- 计算机中日期连接符号,电脑时间不能同步,在命令提示符里输入w32tm
- DELL 7080MFF 黑苹果安装,优化
- Java代码生成图片验证码
- SAX 解析XML文件:将XML转换成Java对象
- PostgreSQL中的距离计算问题 ST_Length
- Psp软件开发过程定位设计
- 一年级计算机课ppt,一年级信息技术全部课程PPT课件.ppt
- 重磅 | GitHub私有仓库从此免费,微软要赢开发者的心
- Java实现面向切面编程(AOP)
- 解决:运行pytest时,报错:'TestCaseFunction' object has no attribute 'get_marker'