libctb库的win版本返回指令遇到00被截断问题

简介: 解决libctb for c++ 在win的Read函数处置不严谨导致返回指令被截断问题

libctb库是c++实现串口通信的第三方扩展库,该是直接提供源码的,可取https://www.iftools.com/start/index.en.php网站的download页面搜索libctb下载其源码,例如libctb-0.16.tar.gz。

其具体编译查看其解压目录下的build即可实现,在实践发现中在读取数据是,会出现数据被截断的情况,例如:

0102002160指令,读取返回0102,后面 数据被抛弃,经源码调试发现,其读取数据是正确的,但在计算长度时将00作为结束符,造成计算长度异常,现给出修改参考,给同样遇到该问题的读者

打开libctb-0.16\src\win32\serport.cpp文件,修改

    int SerialPort::Read(char* buf,size_t len)
    {
	   DWORD read;
	   int m = m_fifo->items();
	   while(len) {
		  if(m_fifo->get(buf) == 1) {
			 len--;
			 buf++;
		  }
		  else {
			 break;
		  }
	   }
	   if(!ReadFile(fd,buf,len,&read,&m_ov)) {
		  // if we use a asynchrone reading, ReadFile gives always
		  // FALSE
		  // ERROR_IO_PENDING means ok, other values show an error
		  if(GetLastError() != ERROR_IO_PENDING) {
			 // oops..., error in communication
			 return -1;
		  }
	   }
	   else {
		  // ok, we have read all wanted bytes
		  return (int)read + m;
	   }
	   return 0;
    };

    int SerialPort::Read(char* buf,size_t len)
    {
	   DWORD read;
	   int m = m_fifo->items();
	   while(len) {
		  if(m_fifo->get(buf) == 1) {
			 len--;
			 buf++;
		  }
		  else {
			 break;
		  }
	   }
	   //printf("SerialPort::Read(%d,%d)..1..\n", m, len);
	   //byte _buf[64] = { 0 };
	   if(!ReadFile(fd,(LPVOID)buf,len,&read,&m_ov)) {
		  // if we use a asynchrone reading, ReadFile gives always
		  // FALSE
		  // ERROR_IO_PENDING means ok, other values show an error
		  if(GetLastError() != ERROR_IO_PENDING) {
			 // oops..., error in communication
			  //printf("SerialPort::Read error(%d)..2..\n", (int)GetLastError());
			 return -1;
		  }
	   }
	   else {
		   //memcpy(buf, _buf, (int)read + m);
		   //printf("SerialPort::Read(%d,%d,%d,%d)..3..\n", m, len,(int)read,strlen(buf));
		  // ok, we have read all wanted bytes
		  return (int)read + m;
	   }
	   //继续处置后续字符,防止被丢弃
	   int size = strlen(buf);
	   for (int i = size; i < len; i++)
	   {
		   if (0X00 != buf[i])
			   size = i+1;
	   }

	   //memcpy(buf, _buf, (int)read + m);
	   //printf("SerialPort::Read(%d,%d,%d,%d)..4..\n", m, len, (int)read, strlen(buf));
	   return size;
    };

完成修改重新编译libctb的调用库, 在调用其Read函数时,可以再加一层保险,就不会出现本文描述的截断情况

char cache[128] = { 0 };
memset(cache, 0x00, 128);
Ret = Read(cache, 128);   // 读应答数据 ascii,结尾字段丢失,明明有数据,却返回长度为0
readlen = (int)strlen(cache);
nrecs = (Ret <  readlen ? readlen : Ret);

if (acssiif)
{
       memcpy(atres, cache, nrecs);
 }
else {
       nrecs = PFunc::bytes2string((const unsigned char*)cache, (char*)atres, nrecs);//ascii to hex
}

目录
相关文章
|
2月前
|
网络协议 API Windows
MASM32v11编程调用Process32First失败: 程序发出命令,但命令长度不正确
MASM32v11编程调用Process32First失败: 程序发出命令,但命令长度不正确
|
6月前
|
Python Windows
Python 执行RD命令的问题汇总(无效开关 - “Image“。)
Python 执行RD命令的问题汇总(无效开关 - “Image“。)
90 0
|
Shell
shell脚本之判断当前内核主版本是否为3,且次版本是否大于10
shell脚本之判断当前内核主版本是否为3,且次版本是否大于10
107 0
|
JavaScript Java
TeaVM当前版本(0.7.0)还不支持传递字串参数
TeaVM当前版本(0.7.0)还不支持传递字串参数
77 0
|
JSON 数据格式
关于 Qt使用QJsonObject解析超范围整数的时候提取value失败 的解决方法
关于 Qt使用QJsonObject解析超范围整数的时候提取value失败 的解决方法
关于 Qt使用QJsonObject解析超范围整数的时候提取value失败 的解决方法
|
前端开发
Cypress系列(22)- 可操作类型的命令 之 select()
Cypress系列(22)- 可操作类型的命令 之 select()
270 0
Cypress系列(22)- 可操作类型的命令 之 select()
|
Python
Python 技术篇-用win32库实现读取、添加、修改注册表的值实例演示
Python 技术篇-用win32库实现读取、添加、修改注册表的值实例演示
537 0
Python 技术篇-用win32库实现读取、添加、修改注册表的值实例演示
|
开发框架 并行计算 .NET
c1xx : warning C4199: C++/CLI、C++/CX 或 OpenMP 不支持两阶段名称查找;请使用 /Zc:twoPhase-
c1xx : warning C4199: C++/CLI、C++/CX 或 OpenMP 不支持两阶段名称查找;请使用 /Zc:twoPhase-
1309 0
VS无法断点调试,编译时为生成pdb文件,不包含调试信息(未加载任何符号)
VS无法断点调试,编译时为生成pdb文件,不包含调试信息(未加载任何符号)
505 0
|
MySQL 关系型数据库 Linux
linux下命令行执行后的返回值-错误值
我们最开始学习的C语言中,主函数中int main()函数的最后总会加一个return 0;充当返回值,当初我们并不知道这个返回值的意义是什么,我们经常使用的是普通函数中的返回值,当函数执行一个任务时,函数执行完毕之后总会返回一个适当的值来告诉执行者该函数执行的情况 Linux 下,在terminal下,控制台下运行命令,所有的命令在结束时,都会返回一个数字值,这个值即为返回值,每个返回值都对应着一个错误号,根据错误号我们可以大致推断这个函数执行的情况。
2010 0