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

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
}

上一篇:qt最小化托盘失焦问题


下一篇:gsoap的c++ server和java client实现