从串行端口c+读取+; 我有下面的C++代码,当我运行程序时,有时它工作,有时它不工作!p>

从串行端口c+读取+; 我有下面的C++代码,当我运行程序时,有时它工作,有时它不工作!p>,c++,visual-studio-2010,winapi,serial-port,windows-xp,C++,Visual Studio 2010,Winapi,Serial Port,Windows Xp,我认为当我试图打开串行端口时,当有数据要读取时,问题就出现了 有时在运行此程序后,它会使Windows XP意外重新启动!它没有蓝屏,只是重新启动 我正在使用VisualStudio2010来编译它 main() { while(0) { // BIG FAT WARNING: MIGHT SUDDEN REBOOT YOUR MACHINE IF ENABLED read_from_serial(_data); } } bool read_from_seria

我认为当我试图打开串行端口时,当有数据要读取时,问题就出现了

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

我正在使用VisualStudio2010来编译它

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;
}
main()
{
while(0){//BIG-FAT警告:如果启用,可能会突然重新启动计算机
从串行数据(数据)读取数据;
}
}
bool从串行读取(八位字节字符串和数据)
{
处理串行;
hSerial=CreateFile(文本(“COM2”),
泛型|泛型|写,0,0,打开|存在,文件|属性|正常,0);
if(hSerial==无效的句柄值)
{
如果(GetLastError()==找不到错误文件)
{
不能引起
我怀疑你的程序在这条线上崩溃了

tmp_receive[dwBytesRead+1]=END_OF_STRING;
您使用
255
元素定义了
tmp\u receive
数组,这使得可能的索引
0
254
。然后您将
len
初始化为
255
。如果调用
ReadFile(…)时有255个字节可读取
,则
dwBytesRead
将等于
255
,上面提到的行实际上如下所示,这意味着您试图写入
tmp\u receive
数组范围之外的内存

tmp_receive[256] = END_OF_STRING;
至于重新启动,我不确定,但当您的程序试图写入无效内存时,可能会导致系统崩溃,并且您将Windows XP配置为重新启动,而不是显示错误


解决 为了防止您的程序崩溃,我看到您有两个选择。我不能说哪一个更好,因为我不知道您希望接收的数据的格式是什么,所以您必须分析每个选择的结果,并自行决定

选项#1

定义
tmp\u接收
数组时,使用
257
元素计数

tmp_receive[256] = END_OF_STRING;
选项2

调用
ReadFile(…)


补充资料
  • 有关
    ReadFile(…)
    Windows API行为的更多信息,请参阅上的MSDN文档

  • 如果您想了解更多关于字符串如何存储在内存中的信息,我建议您阅读关于字符串的文章


  • <代码> >你的实际程序是什么样子的?<代码>有时运行这个程序使我的XP操作系统重新启动!< /代码>哇!我建议你不要运行它。它是蓝色屏幕吗?什么是错误?事件日志中有什么?Windows更新?这个程序没有编译。也许编译器使你的XP操作系统重新启动?考虑使用另一个程序。编译器。扔掉适配器。换一个具有更好驱动程序的适配器。另外,您不需要声明tmp_buf,只需执行_data.append(tmp_receive)