我有以下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;
}
答案 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))
有关ReadFile(...)
Windows API行为的详细信息,请查看ReadFile(...)
上的MSDN文档。
如果您想详细了解字符串在内存中的存储方式,建议您查看Character Sequences上的www.cplusplus.com文章。