代码如下:
//先获取COM口状态
if(ClearCommError(m_COMHandle, &error, &stat) && error > 0) //清除错误
{
PurgeComm(m_COMHandle, PURGE_TXABORT | PURGE_TXCLEAR); /*清除输入缓冲区*/
return false;
}
//ClearCommError(m_COMHandle, &error, &stat);

unsigned long len = 0;
char buf[64];
len =(int)stat.cbInQue; //将缓冲区中的全部数据都取出
if (len<m_nbarCodeLen) //没有达到指定的数据长度则退出
{
return false;
}
if(!ReadFile(m_COMHandle, buf, len, &len, NULL)) //取数据失败
{
len = 0;
}
buf[len] = '\0';使用以上代码从COM口获取数据,在非线程中调用时没有任何问题,但是在线程中调用失败,每次CLEARCOMMERROR时都出现错误16,MSDN的解释是CE_BREAK The hardware detected a break condition. 
请问有大虾遇到过同样的问题没有?

解决方案 »

  1.   

    线程不安全,建议重看msdn祥解
      

  2.   

    没有遇到过,建立楼主查查m_COMHandle。线程使用的指针啥的。。
      

  3.   

    一气之下,贴出全部代码献丑了,请各位指点下,急得不行了
    cpp文件
    CSJYTScannerDLL::CSJYTScannerDLL()

    //默认设置为:COM,9600,条码长度13
    m_nComRate = 9600;
    m_nCOM = 1;
    m_nbarCodeLen=13;
        m_COMHandle = INVALID_HANDLE_VALUE;
    return; 
    }bool CSJYTScannerDLL::OpenScanner(int nCOM,long nComRate)
    {
    //连接条码扫描仪
    char szPort[10];
    m_nCOM = nCOM;
    m_nComRate = nComRate;
    sprintf(szPort, "COM%d", nCOM);
    m_COMHandle = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE ==  m_COMHandle)
    {
            return false;
    }
    //说明:关键在于初始化超时设置和设备控制设置
        COMMTIMEOUTS CommtimeOuts;
    memset((void*)&CommtimeOuts, 0, sizeof(CommtimeOuts));
    CommtimeOuts.ReadIntervalTimeout = 0x10;
    CommtimeOuts.ReadTotalTimeoutMultiplier = 1;
    CommtimeOuts.ReadTotalTimeoutConstant = 1;
    CommtimeOuts.WriteTotalTimeoutConstant = 1;
    CommtimeOuts.WriteTotalTimeoutMultiplier = 1;//5000;
    SetCommTimeouts(m_COMHandle, &CommtimeOuts);

        DCB dcb;
    memset((void*)&dcb, 0, sizeof(dcb));
    GetCommState(m_COMHandle, &dcb);
    dcb.BaudRate = m_nComRate;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.EofChar = 0;
    dcb.ErrorChar = 0;
    dcb.EvtChar = 0;
    dcb.fErrorChar = 0;
    dcb.XoffChar = 0x13;
    dcb.XonChar = 0x11;
    dcb.XonLim = 2048;
    dcb.XoffLim = 512;
    dcb.fBinary = TRUE;
    //设置超时和设备控制设置
    if (!SetCommState(m_COMHandle, &dcb) 
            || !SetupComm(m_COMHandle, 64, 64))
    {
    CloseScanner();
    }
    //清除所有缓冲区
    PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
        return true;
    }bool CSJYTScannerDLL::CloseScanner()
    {
    //断开条码扫描仪连接
    if (INVALID_HANDLE_VALUE == m_COMHandle)
    {
            return true;
    }
        PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    //关键在于关闭设备句柄
    CloseHandle(m_COMHandle);
        m_COMHandle = INVALID_HANDLE_VALUE;
    return true;
    }bool CSJYTScannerDLL::GetBarCode(char * szBarCode)
    {
    //memset(szBarCode,0,255);
    szBarCode[0] = '\0';

    COMSTAT  stat;
    DWORD error;
    unsigned long len = 0;
    char buf[64];
    //先获取COM口状态 if(ClearCommError(m_COMHandle, &error, &stat) && error > 0) //清除错误
    {
    //PurgeComm(m_COMHandle, PURGE_TXABORT | PURGE_TXCLEAR); //清除输入缓冲区
    return false;
    }
    //ClearCommError(m_COMHandle, &error, &stat);


    len =(int)stat.cbInQue; //将缓冲区中的全部数据都取出
    if (len<m_nbarCodeLen) //没有达到指定的数据长度则退出
    {
    return false;
    } if(!ReadFile(m_COMHandle, buf, len, &len, NULL)) //取数据失败
    {
    len = 0;
    }
    buf[len] = '\0';
    if (len<m_nbarCodeLen) //如果没有获取足够长的
    {
    return false;
    }
    //如果有足够长的数据则获取截取最新的一个条码长度
    for (int nCount=0;nCount<m_nbarCodeLen;++nCount)
    {
    szBarCode[nCount]=buf[len-m_nbarCodeLen-1+nCount];
    }
    szBarCode[nCount]='\0';
    return true;
    }bool CSJYTScannerDLL::ClearComData()
    {
    //清除可能存在的COM缓冲区数据
    if (INVALID_HANDLE_VALUE == m_COMHandle)
    {
            return true;
    }
    PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    return true;
    }bool CSJYTScannerDLL::SetBarCodeLen(int len)
    {
    if (INVALID_HANDLE_VALUE == m_COMHandle)
    {
            return false;
    }
    m_nbarCodeLen=len;
    return true;
    }///H文件
    class SJYTSCANNERDLL_API CSJYTScannerDLL {
    public:
    CSJYTScannerDLL(void); //构造函数
    bool OpenScanner(int nCOM,long nComRate); //连接扫描仪
    bool CloseScanner(); //断开扫描仪
    bool SetBarCodeLen(int len); //设置读取的条码长度
    bool GetBarCode(char * szBarCode); //获取条码
    bool ClearComData(); //清除条码仪的缓冲区数据
    private:
    int m_nCOM; //COM端口
    long m_nComRate; //COM口速率
    HANDLE m_COMHandle; //COM句柄
    DCB dcb; //DCB
    COMMTIMEOUTS commtimeouts; //超时设置
    int m_nbarCodeLen; //条码长度 //CString m_szCOM;
    // TODO: add your methods here.
    };
      

  4.   

    试了下直接从COM口取数据,在COM口有数据输入时每次都是数据长度为38,COM口状态为16,获取的数据为混乱状态(线程中调用,调用时已经进行线程同步)
    在非线程中调用正常
    请各位帮帮忙看下什么地方有问题!
      

  5.   

    非常遗憾没能帮上忙
    楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
    也可以给大家长长见识
      

  6.   

    非常遗憾没能帮上忙
    楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
    也可以给大家长长见识
      

  7.   

    非常遗憾没能帮上忙
    楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
    也可以给大家长长见识