从串口c ++读取

时间:2011-11-08 09:01:50

标签: c++ visual-studio-2010 winapi serial-port windows-xp

我有以下C ++代码,当我运行程序时,它有时会运行,有时它不会!

我认为当我想要读取数据时尝试打开串口时会出现问题。

有时在运行此程序后,它会使Windows XP意外重启!它不是蓝屏,它只是重新启动。

我正在使用Visual Studio 2010来编译它。

main()
{
    while(0) { // BIG FAT WARNING: MIGHT SUDDEN REBOOT YOUR MACHINE IF ENABLED
        read_from_serial(_data);
    }
}

bool read_from_serial(octed_string &_data)
{
    HANDLE hSerial;
    hSerial = CreateFile(TEXT("COM2"),
                         GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    if (hSerial == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_FILE_NOT_FOUND)
        {
            cout << "1:";
            return false;
        //serialportdoesnotexist.Informuser.
        }
        cout << "2:";
        return false;

        //someothererroroccurred.Informuser.
    }

    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength=sizeof(dcbSerialParams);

    if(!GetCommState(hSerial,&dcbSerialParams))
    {
        cout<<"3:";
        return false;
        //errorgettingstate
    }

    dcbSerialParams.BaudRate=CBR_9600;
    dcbSerialParams.ByteSize=7;
    dcbSerialParams.StopBits=ONESTOPBIT;
    dcbSerialParams.Parity=EVENPARITY;

    if (!SetCommState(hSerial,&dcbSerialParams))
    {
        cout<<"4:";
        return false;
        //errorsettingserialportstate
    }

    COMMTIMEOUTS timeouts={0};
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=10;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;

    if (!SetCommTimeouts(hSerial,&timeouts))
    {
        cout<<"5:";
        return false;
        //erroroccureed.Informuser
    }

    const int n=1;

    DWORD dwBytesRead=0;

    char_t tmp_receive[255]={0};

    char_t buff[255];

    int len=255;

    if (!ReadFile(hSerial,tmp_receive,len,&dwBytesRead,NULL))
    {
        cout<<"6:";
        CloseHandle(hSerial);
        return false;
    }

    CloseHandle(hSerial);

    tmp_receive[dwBytesRead+1]=END_OF_STRING;
    string tmp_buff_str=tmp_receive;
    _data.append(tmp_buff_str);
    return true;
}

1 个答案:

答案 0 :(得分:1)

原因

我怀疑你的程序正在崩溃

tmp_receive[dwBytesRead+1]=END_OF_STRING;

您使用tmp_receive元素定义了255数组,这使得可能的索引0变为254。然后,您将len初始化为255。如果有{255}字节可供读取ReadFile(...),那么dwBytesRead将等于255,上面提到的第一行将实际如下,并且意味着你'重新尝试写入tmp_receive数组范围之外的内存。

tmp_receive[256] = END_OF_STRING;

至于重新启动,我不确定,但是当你的程序尝试写入无效内存而你的程序导致系统崩溃并且Windows XP配置为重新启动而不是显示BSOD时。


解决方案

为了防止程序崩溃,我发现你有两个选择。我不知道哪一个更好,因为我不知道你期望收到的数据格式是什么,所以你必须分析每个选项的结果并自己决定。

选项#1

在定义257数组时使用元素数tmp_receive

选项#2

在致电len

时从ReadFile(...)减去2
if (!ReadFile(hSerial,tmp_receive,len-2,&dwBytesRead,NULL))

其他信息